Merge remote-tracking branch 'space-wizards/master'
# Conflicts: # .github/workflows/publish.yml # Content.Client/Clothing/ClientClothingSystem.cs # Content.Client/Clothing/Systems/ChameleonClothingSystem.cs # Content.Client/Fax/UI/FaxWindow.xaml # Content.Client/Ghost/GhostSystem.cs # Content.Client/Holiday/HolidaySystem.cs # Content.Client/Humanoid/HumanoidAppearanceSystem.cs # Content.Client/Lobby/UI/Loadouts/LoadoutWindow.xaml.cs # Content.Client/Lobby/UI/LobbyGui.xaml # Content.Client/Lobby/UI/LobbyGui.xaml.cs # Content.Client/Mech/MechSystem.cs # Content.Client/Stealth/StealthSystem.cs # Content.Client/Weapons/Ranged/Systems/GunSystem.cs # Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs # Content.Server/Bed/BedSystem.cs # Content.Server/Body/Systems/BodySystem.cs # Content.Server/Body/Systems/RespiratorSystem.cs # Content.Server/Cargo/Systems/CargoSystem.Orders.cs # Content.Server/Communications/CommunicationsConsoleComponent.cs # Content.Server/EntityEffects/Effects/AreaReactionEffect.cs # Content.Server/EntityEffects/Effects/MakeSentient.cs # Content.Server/EntityEffects/Effects/PlantMetabolism/PlantAdjustPests.cs # Content.Server/EntityEffects/Effects/PlantMetabolism/PlantAdjustToxins.cs # Content.Server/EntityEffects/Effects/PlantMetabolism/PlantAdjustWeeds.cs # Content.Server/EntityEffects/Effects/PlantMutateGases.cs # Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs # Content.Server/GameTicking/GameTicker.Spawning.cs # Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs # Content.Server/IoC/ServerContentIoC.cs # Content.Server/Nutrition/EntitySystems/FoodSystem.cs # Content.Server/Power/EntitySystems/PowerNetSystem.cs # Content.Server/Preferences/Managers/ServerPreferencesManager.cs # Content.Server/RoundEnd/RoundEndSystem.cs # Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs # Content.Server/Station/Systems/StationSpawningSystem.cs # Content.Server/VoiceMask/VoiceMaskSystem.cs # Content.Server/Weapons/Ranged/Systems/GunSystem.cs # Content.Shared/Bed/Components/HealOnBuckleComponent.cs # Content.Shared/Clothing/EntitySystems/ClothingSystem.cs # Content.Shared/EntityEffects/Effects/ExplosionReactionEffect.cs # Content.Shared/Inventory/InventorySystem.Relay.cs # Content.Shared/Item/ItemToggle/Components/ComponentTogglerComponent.cs # Content.Shared/Preferences/HumanoidCharacterProfile.cs # Content.Shared/Preferences/Loadouts/RoleLoadout.cs # Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs # Content.Shared/Wieldable/SharedWieldableSystem.cs # Resources/Audio/Machines/attributions.yml # Resources/Locale/en-US/_strings/atmos/plaque-component.ftl # Resources/Locale/en-US/_strings/chat/chat-channel.ftl # Resources/Locale/en-US/_strings/components/screen-component.ftl # Resources/Locale/en-US/_strings/inventory/components/slot-block-component.ftl # Resources/Locale/en-US/_strings/mass-media/news-discord.ftl # Resources/Locale/en-US/_strings/objectives/commands/stripall.ftl # Resources/Locale/en-US/_strings/salvage/job-board.ftl # Resources/Locale/en-US/_strings/ui/spray-painter-window.ftl # Resources/Locale/en-US/_strings/ui/turret-controls.ftl # Resources/Maps/_Sunrise/Station/box.yml # Resources/Prototypes/Access/misc.yml # Resources/Prototypes/Catalog/Fills/Boxes/emergency.yml # Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml # Resources/Prototypes/Catalog/Fills/Lockers/heads.yml # Resources/Prototypes/Catalog/Fills/Lockers/service.yml # Resources/Prototypes/Catalog/Fills/Lockers/suit_storage.yml # Resources/Prototypes/Entities/Clothing/Head/helmets.yml # Resources/Prototypes/Entities/Clothing/Masks/masks.yml # Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml # Resources/Prototypes/Entities/Markers/Spawners/mobs.yml # Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml # Resources/Prototypes/Entities/Mobs/NPCs/animals.yml # Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml # Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml # Resources/Prototypes/Entities/Mobs/Player/dragon.yml # Resources/Prototypes/Entities/Mobs/Player/silicon.yml # Resources/Prototypes/Entities/Mobs/Species/arachnid.yml # Resources/Prototypes/Entities/Mobs/Species/moth.yml # Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml # Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml # Resources/Prototypes/LootTables/suspicion_loot_table.yml # Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml # Resources/Prototypes/Reagents/medicine.yml # Resources/Prototypes/Recipes/Lathes/Packs/science.yml # Resources/Prototypes/Recipes/Lathes/medical.yml # Resources/Prototypes/SoundCollections/NukeMusic.yml # Resources/ServerInfo/Guidebook/Cargo/Salvage.xml # Resources/Textures/Clothing/Hands/Gloves/KnuckleDusters/brassknuckleduster.rsi/equipped-OUTERCLOTHING-reptilian.png # Resources/Textures/Clothing/OuterClothing/Hardsuits/basic.rsi/meta.json # Resources/Textures/Clothing/OuterClothing/Suits/eva.rsi/meta.json # Resources/Textures/Clothing/OuterClothing/Suits/eva_emergency.rsi/meta.json # Resources/Textures/Clothing/OuterClothing/Suits/eva_prisoner.rsi/meta.json # Resources/Textures/Effects/speech.rsi/alien3.png # Resources/Textures/Effects/speech.rsi/alienroyal3.png # Resources/Textures/Effects/speech.rsi/default3.png # Resources/Textures/Effects/speech.rsi/guardian3.png # Resources/Textures/Effects/speech.rsi/holo3.png # Resources/Textures/Effects/speech.rsi/lawyer3.png # Resources/Textures/Effects/speech.rsi/lizard3.png # Resources/Textures/Effects/speech.rsi/meta.json # Resources/Textures/Effects/speech.rsi/moth3.png # Resources/Textures/Effects/speech.rsi/robot3.png # Resources/Textures/Effects/speech.rsi/slime3.png # Resources/Textures/Effects/speech.rsi/spider3.png # Resources/Textures/Effects/speech.rsi/syndibot3.png # Resources/Textures/Interface/Misc/job_icons.rsi/meta.json # Resources/Textures/Mobs/Silicon/chassis.rsi/meta.json # Resources/Textures/Mobs/Species/Reptilian/parts.rsi/head_f.png # Resources/Textures/Mobs/Species/Reptilian/parts.rsi/head_m.png # Resources/Textures/Objects/Misc/id_cards.rsi/meta.json # Resources/Textures/Structures/Doors/Airlocks/Glass/external.rsi/emergency_unlit.png # Resources/Textures/Structures/Piping/disposal.rsi/meta.json # Resources/Textures/Tiles/attributions.yml # Resources/Textures/Tiles/steel_dirty.png # Resources/migration.yml # runclient-Tools.bat # runclient.bat
This commit is contained in:
commit
d6c0a011b7
1712 changed files with 327602 additions and 284989 deletions
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
|
|
@ -8,7 +8,7 @@
|
|||
/Resources/ServerInfo/ @nikthechampiongr @crazybrain23
|
||||
/Resources/ServerInfo/Guidebook/ServerRules/ @nikthechampiongr @crazybrain23
|
||||
|
||||
/Resources/Prototypes/Maps/** @Emisse
|
||||
/Resources/Prototypes/Maps/** @Emisse @ArtisticRoomba
|
||||
|
||||
/Resources/Prototypes/Body/ @DrSmugleaf # suffering
|
||||
/Resources/Prototypes/Entities/Mobs/Player/ @DrSmugleaf
|
||||
|
|
|
|||
54
.github/workflows/check-trailing-whitespace.yml
vendored
Normal file
54
.github/workflows/check-trailing-whitespace.yml
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
name: Trailing Whitespace Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [ opened, reopened, synchronize, ready_for_review ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Trailing Whitespace Check
|
||||
if: github.event.pull_request.draft == false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
- name: Get changed text files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v46.0.5
|
||||
with:
|
||||
files: |
|
||||
**.cs
|
||||
**.yml
|
||||
**.swsl
|
||||
**.json
|
||||
**.py
|
||||
- name: Check for trailing whitespace and EOF newline
|
||||
env:
|
||||
ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||
run: |
|
||||
has_trailing_whitespace=0
|
||||
has_missing_eof_newline=0
|
||||
|
||||
for file in ${ALL_CHANGED_FILES}; do
|
||||
echo "Checking $file"
|
||||
|
||||
# Check for trailing whitespace
|
||||
if grep -qP '[ \t]+$' "$file"; then
|
||||
echo "::error file=$file::Trailing whitespace found"
|
||||
has_trailing_whitespace=1
|
||||
fi
|
||||
|
||||
# Check for missing EOF newline
|
||||
if [ -f "$file" ] && [ -s "$file" ]; then
|
||||
last_char=$(tail -c 1 "$file")
|
||||
if [ "$last_char" != "" ] && [ "$last_char" != $'\n' ]; then
|
||||
echo "::error file=$file::Missing newline at end of file"
|
||||
has_missing_eof_newline=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$has_trailing_whitespace" -eq 1 ] || [ "$has_missing_eof_newline" -eq 1 ]; then
|
||||
echo "Issues found: trailing whitespace or missing EOF newline."
|
||||
echo "We recommend using an IDE to prevent this from happening."
|
||||
exit 1
|
||||
fi
|
||||
1
.github/workflows/publish-testing.yml
vendored
1
.github/workflows/publish-testing.yml
vendored
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
concurrency:
|
||||
group: publish-testing
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
|
|
|||
4
.github/workflows/publish.yml
vendored
4
.github/workflows/publish.yml
vendored
|
|
@ -2,6 +2,7 @@ name: Publish
|
|||
|
||||
concurrency:
|
||||
group: publish
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
|
@ -68,18 +69,21 @@ jobs:
|
|||
DISCORD_WEBHOOK_URL: ${{ secrets.CHANGELOG_DISCORD_WEBHOOK_SUNRISE }}
|
||||
|
||||
- name: Publish discord changelog (LUST)
|
||||
continue-on-error: true
|
||||
run: Tools/_sunrise/actions_changelogs_since_last_run.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.CHANGELOG_DISCORD_WEBHOOK_LUST }}
|
||||
|
||||
- name: Publish discord changelog (FISH)
|
||||
continue-on-error: true
|
||||
run: Tools/_sunrise/actions_changelogs_since_last_run.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.CHANGELOG_DISCORD_WEBHOOK_FISH }}
|
||||
|
||||
# - name: Publish changelog (RSS)
|
||||
# continue-on-error: true
|
||||
# run: Tools/actions_changelog_rss.py
|
||||
# env:
|
||||
# CHANGELOG_RSS_KEY: ${{ secrets.CHANGELOG_RSS_KEY }}
|
||||
|
|
|
|||
40
CODE_OF_CONDUCT.md
Normal file
40
CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Space Station 14 Code of Conduct
|
||||
|
||||
Space Station 14's staff and community is made up volunteers from all over the world, working on every aspect of the project - including development, teaching, and hosting integral tools.
|
||||
|
||||
Diversity is one of our huge strengths, but it can also lead to communication issues and unhappiness. To that end, we have a few ground rules that we ask people to adhere to. This code applies equally to all levels of the project, from commenters to contributors to staff.
|
||||
|
||||
This isn’t an exhaustive list of things that you can’t do. Rather, take it in the spirit in which it’s intended - a guide to make it easier to enrich all of us and the technical communities in which we participate.
|
||||
|
||||
This code of conduct applies specifically to the Github repositories and its spaces managed by the Space Station 14 project or Space Wizards Federation. Some spaces, such as the Space Station 14 Discord or the official Wizard's Den game servers, have their own rules but are in spirit equal to what may be found in here.
|
||||
|
||||
If you believe someone is violating the code of conduct, we ask that you report it by contacting a Maintainer, Project Manager or Wizard staff member through [Discord](https://discord.ss14.io/), [the forums](https://forum.spacestation14.com/), or emailing [telecommunications@spacestation14.com](mailto:telecommunications@spacestation14.com).
|
||||
|
||||
- **Be friendly and patient.**
|
||||
- **Be welcoming.** We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, colour, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability.
|
||||
- **Be considerate.** Your work will be used by other people, and you in turn will depend on the work of others. Any decision you take will affect users and contributors, and you should take those consequences into account when making decisions. Remember that we're a world-wide community, so you might not be communicating in someone else's primary language. We have contributors of all skill levels, some even making their first foray into a new field with this project, so keep that in mind when discussing someone's work.
|
||||
- **Be respectful.** Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It’s important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the Space Station 14 community should be respectful when dealing with other members as well as with people outside the Space Station 14 community. Assume contributions to the project, even those that do not end up being included, are made in good faith.
|
||||
- **Be careful in the words that you choose.** We are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. This includes, but is not limited to:
|
||||
- Violent threats or language directed against another person.
|
||||
- Discriminatory jokes and language.
|
||||
- Posting sexually explicit or violent material.
|
||||
- Posting (or threatening to post) other people's personally identifying information ("doxing").
|
||||
- Personal insults, especially those using racist or sexist terms.
|
||||
- Unwelcome sexual attention.
|
||||
- Advocating for, or encouraging, any of the above behavior.
|
||||
- Repeated harassment of others. In general, if someone asks you to stop, then stop.
|
||||
- **When we disagree, try to understand why.** Disagreements, both social and technical, happen all the time and Space Station 14 is no exception. It is important that we resolve disagreements and differing views constructively. Remember that we’re different. The strength of Space Station 14 comes from its varied community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn’t mean that they’re wrong. Don’t forget that it is human to make mistakes and blaming each other doesn’t get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes.
|
||||
|
||||
Original text courtesy of the [Speak Up! project](http://web.archive.org/web/20141109123859/http://speakup.io/coc.html).
|
||||
|
||||
## On Comunity Moderation
|
||||
|
||||
Deviating from the Code of Conduct on the Github repository may result in moderative actions taken by project Maintainers. This can involve your content being edited or deleted, and may result in a temporary or permanent block from the repository.
|
||||
|
||||
This is to ensure Space Station 14 is a healthy community in which contributors feel encouraged and empowered to contribute, and to give you as a member of this community a chance to reflect on how you are interacting with it. While outright offensive and bigoted content will *always* be unacceptable on the repository, Maintainers are at liberty to take moderative actions against more ambiguous content that fail to provide constructive criticism, or that provides constructive criticism in a non-constructive manner. Examples of this include using hyperbole, bringing up PRs/changes unrelated to the discussion at hand, hostile tone, off-topic comments, creating PRs/Issues for the sole purpose of causing discussions, skirting the line of acceptable behavior, etc. Disagreeing with content or each other is fine and appreciated, but only as long as it's done with respect and in a constructive manner.
|
||||
|
||||
Maintainers are expected to adhere to the guidelines as listed in the [Github Moderation Guidelines](https://docs.spacestation14.com/en/general-development/github-moderation-guidelines.html), though may deviate should they feel it's in the best interest of the community. If you believe you had an action incorrectly applied against you, you are encouraged to contact staff via [Discord](https://discord.ss14.io/) or [the forums](https://forum.spacestation14.com/), [appeal your Github ban](https://forum.spacestation14.com/c/ban-appeals/appeals-github/38), or make a [staff complaint](https://forum.spacestation14.com/t/staff-complaint-instructions-and-info/31).
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is an edited version of the [Django Code of Conduct](https://www.djangoproject.com/conduct/), licensed under CC BY 3.0, for the Space Station 14 Github repository.
|
||||
|
|
@ -29,7 +29,7 @@ namespace Content.Benchmarks;
|
|||
[CategoriesColumn]
|
||||
public class ComponentQueryBenchmark
|
||||
{
|
||||
public const string Map = "Maps/atlas.yml";
|
||||
public const string Map = "Maps/saltern.yml";
|
||||
|
||||
private TestPair _pair = default!;
|
||||
private IEntityManager _entMan = default!;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,7 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BenchmarkDotNet.Running;
|
||||
using Content.IntegrationTests;
|
||||
using Content.Server.Maps;
|
||||
#if DEBUG
|
||||
using BenchmarkDotNet.Configs;
|
||||
#else
|
||||
using Robust.Benchmarks.Configs;
|
||||
#endif
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Benchmarks
|
||||
{
|
||||
|
|
@ -22,11 +14,15 @@ namespace Content.Benchmarks
|
|||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("\nWARNING: YOU ARE RUNNING A DEBUG BUILD, USE A RELEASE BUILD FOR AN ACCURATE BENCHMARK");
|
||||
Console.WriteLine("THE DEBUG BUILD IS ONLY GOOD FOR FIXING A CRASHING BENCHMARK\n");
|
||||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new DebugInProcessConfig());
|
||||
var baseConfig = new DebugInProcessConfig();
|
||||
#else
|
||||
var config = Environment.GetEnvironmentVariable("ROBUST_BENCHMARKS_ENABLE_SQL") != null ? DefaultSQLConfig.Instance : null;
|
||||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config);
|
||||
var baseConfig = Environment.GetEnvironmentVariable("ROBUST_BENCHMARKS_ENABLE_SQL") != null
|
||||
? DefaultSQLConfig.Instance
|
||||
: DefaultConfig.Instance;
|
||||
#endif
|
||||
var config = ManualConfig.Create(baseConfig);
|
||||
config.BuildTimeout = TimeSpan.FromMinutes(5);
|
||||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
126
Content.Benchmarks/RaiseEventBenchmark.cs
Normal file
126
Content.Benchmarks/RaiseEventBenchmark.cs
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#nullable enable
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Content.IntegrationTests;
|
||||
using Content.IntegrationTests.Pair;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Benchmarks;
|
||||
|
||||
[Virtual]
|
||||
public class RaiseEventBenchmark
|
||||
{
|
||||
private TestPair _pair = default!;
|
||||
private BenchSystem _sys = default!;
|
||||
|
||||
[GlobalSetup]
|
||||
public void Setup()
|
||||
{
|
||||
ProgramShared.PathOffset = "../../../../";
|
||||
PoolManager.Startup(typeof(BenchSystem).Assembly);
|
||||
_pair = PoolManager.GetServerClient().GetAwaiter().GetResult();
|
||||
var entMan = _pair.Server.EntMan;
|
||||
_sys = entMan.System<BenchSystem>();
|
||||
|
||||
_pair.Server.WaitPost(() =>
|
||||
{
|
||||
var uid = entMan.Spawn();
|
||||
_sys.Ent = new(uid, entMan.GetComponent<TransformComponent>(uid));
|
||||
_sys.Ent2 = new(_sys.Ent.Owner, _sys.Ent.Comp);
|
||||
})
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
}
|
||||
|
||||
[GlobalCleanup]
|
||||
public async Task Cleanup()
|
||||
{
|
||||
await _pair.DisposeAsync();
|
||||
PoolManager.Shutdown();
|
||||
}
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public int RaiseEvent()
|
||||
{
|
||||
return _sys.RaiseEvent();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int RaiseCompEvent()
|
||||
{
|
||||
return _sys.RaiseCompEvent();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int RaiseICompEvent()
|
||||
{
|
||||
return _sys.RaiseICompEvent();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int RaiseCSharpEvent()
|
||||
{
|
||||
return _sys.CSharpEvent();
|
||||
}
|
||||
|
||||
public sealed class BenchSystem : EntitySystem
|
||||
{
|
||||
public Entity<TransformComponent> Ent;
|
||||
public Entity<IComponent> Ent2;
|
||||
|
||||
public delegate void EntityEventHandler(EntityUid uid, TransformComponent comp, ref BenchEv ev);
|
||||
|
||||
public event EntityEventHandler? OnCSharpEvent;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<TransformComponent, BenchEv>(OnEvent);
|
||||
OnCSharpEvent += OnEvent;
|
||||
}
|
||||
|
||||
public int RaiseEvent()
|
||||
{
|
||||
var ev = new BenchEv();
|
||||
RaiseLocalEvent(Ent.Owner, ref ev);
|
||||
return ev.N;
|
||||
}
|
||||
|
||||
public int RaiseCompEvent()
|
||||
{
|
||||
var ev = new BenchEv();
|
||||
EntityManager.EventBus.RaiseComponentEvent(Ent.Owner, Ent.Comp, ref ev);
|
||||
return ev.N;
|
||||
}
|
||||
|
||||
public int RaiseICompEvent()
|
||||
{
|
||||
// Raise with an IComponent instead of concrete type
|
||||
var ev = new BenchEv();
|
||||
EntityManager.EventBus.RaiseComponentEvent(Ent2.Owner, Ent2.Comp, ref ev);
|
||||
return ev.N;
|
||||
}
|
||||
|
||||
public int CSharpEvent()
|
||||
{
|
||||
var ev = new BenchEv();
|
||||
OnCSharpEvent?.Invoke(Ent.Owner, Ent.Comp, ref ev);
|
||||
return ev.N;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private void OnEvent(EntityUid uid, TransformComponent component, ref BenchEv args)
|
||||
{
|
||||
args.N += uid.Id;
|
||||
}
|
||||
|
||||
[ByRefEvent]
|
||||
public struct BenchEv
|
||||
{
|
||||
public int N;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
Content.Client/Access/UI/GroupedAccessLevelChecklist.xaml
Normal file
26
Content.Client/Access/UI/GroupedAccessLevelChecklist.xaml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<BoxContainer xmlns="https://spacestation14.io"
|
||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
Orientation="Horizontal"
|
||||
Margin="10 10 10 10"
|
||||
VerticalExpand="True"
|
||||
HorizontalExpand="True"
|
||||
MinHeight="70">
|
||||
|
||||
<!-- Access groups -->
|
||||
<BoxContainer Name="AccessGroupList" Access="Public" Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.5" Margin="0 0 10 0">
|
||||
<!-- Populated with C# code -->
|
||||
</BoxContainer>
|
||||
|
||||
<PanelContainer StyleClasses="LowDivider" VerticalExpand="True" Margin="0 0 0 0" SetWidth="2">
|
||||
<PanelContainer.PanelOverride>
|
||||
<gfx:StyleBoxFlat BackgroundColor="#FFFFFF" />
|
||||
</PanelContainer.PanelOverride>
|
||||
</PanelContainer>
|
||||
|
||||
<!-- Access levels -->
|
||||
<ScrollContainer HorizontalExpand="True" VerticalExpand="True" Margin="10 0 0 0">
|
||||
<BoxContainer Name="AccessLevelChecklist" Access="Public" Orientation="Vertical" HorizontalAlignment="Left">
|
||||
<!-- Populated with C# code -->
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
449
Content.Client/Access/UI/GroupedAccessLevelChecklist.xaml.cs
Normal file
449
Content.Client/Access/UI/GroupedAccessLevelChecklist.xaml.cs
Normal file
|
|
@ -0,0 +1,449 @@
|
|||
using Content.Client.Stylesheets;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Access;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Content.Client.Access.UI;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class GroupedAccessLevelChecklist : BoxContainer
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||
|
||||
private bool _isMonotone;
|
||||
private string? _labelStyleClass;
|
||||
|
||||
// Access data
|
||||
private HashSet<ProtoId<AccessGroupPrototype>> _accessGroups = new();
|
||||
private HashSet<ProtoId<AccessLevelPrototype>> _accessLevels = new();
|
||||
private HashSet<ProtoId<AccessLevelPrototype>> _activeAccessLevels = new();
|
||||
|
||||
// Button groups
|
||||
private readonly ButtonGroup _accessGroupsButtons = new();
|
||||
|
||||
// Temp values
|
||||
private int _accessGroupTabIndex = 0;
|
||||
private bool _canInteract = false;
|
||||
private List<AccessLevelPrototype> _accessLevelsForTab = new();
|
||||
private readonly List<AccessLevelEntry> _accessLevelEntries = new();
|
||||
private readonly Dictionary<AccessGroupPrototype, List<AccessLevelPrototype>> _groupedAccessLevels = new();
|
||||
|
||||
// Events
|
||||
public event Action<HashSet<ProtoId<AccessLevelPrototype>>, bool>? OnAccessLevelsChangedEvent;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a UI control for changing access levels.
|
||||
/// Access levels are organized under a list of tabs by their associated access group.
|
||||
/// </summary>
|
||||
public GroupedAccessLevelChecklist()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
private void ArrangeAccessControls()
|
||||
{
|
||||
// Create a list of known access groups with which to populate the UI
|
||||
_groupedAccessLevels.Clear();
|
||||
|
||||
foreach (var accessGroup in _accessGroups)
|
||||
{
|
||||
if (!_protoManager.TryIndex(accessGroup, out var accessGroupProto))
|
||||
continue;
|
||||
|
||||
_groupedAccessLevels.Add(accessGroupProto, new());
|
||||
}
|
||||
|
||||
// Ensure that the 'general' access group is added to handle
|
||||
// misc. access levels that aren't associated with any group
|
||||
if (_protoManager.TryIndex<AccessGroupPrototype>("General", out var generalAccessProto))
|
||||
_groupedAccessLevels.TryAdd(generalAccessProto, new());
|
||||
|
||||
// Assign known access levels with their associated groups
|
||||
foreach (var accessLevel in _accessLevels)
|
||||
{
|
||||
if (!_protoManager.TryIndex(accessLevel, out var accessLevelProto))
|
||||
continue;
|
||||
|
||||
var assigned = false;
|
||||
|
||||
foreach (var (accessGroup, accessLevels) in _groupedAccessLevels)
|
||||
{
|
||||
if (!accessGroup.Tags.Contains(accessLevelProto.ID))
|
||||
continue;
|
||||
|
||||
assigned = true;
|
||||
_groupedAccessLevels[accessGroup].Add(accessLevelProto);
|
||||
}
|
||||
|
||||
if (!assigned && generalAccessProto != null)
|
||||
_groupedAccessLevels[generalAccessProto].Add(accessLevelProto);
|
||||
}
|
||||
|
||||
// Remove access groups that have no assigned access levels
|
||||
foreach (var (group, accessLevels) in _groupedAccessLevels)
|
||||
{
|
||||
if (accessLevels.Count == 0)
|
||||
_groupedAccessLevels.Remove(group);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryRebuildAccessGroupControls()
|
||||
{
|
||||
AccessGroupList.DisposeAllChildren();
|
||||
AccessLevelChecklist.DisposeAllChildren();
|
||||
|
||||
// No access level prototypes were assigned to any of the access level groups.
|
||||
// Either the turret controller has no assigned access levels or their names were invalid.
|
||||
if (_groupedAccessLevels.Count == 0)
|
||||
return false;
|
||||
|
||||
// Reorder the access groups alphabetically
|
||||
var orderedAccessGroups = _groupedAccessLevels.Keys.OrderBy(x => x.GetAccessGroupName()).ToList();
|
||||
|
||||
// Add group access buttons to the UI
|
||||
foreach (var accessGroup in orderedAccessGroups)
|
||||
{
|
||||
var accessGroupButton = CreateAccessGroupButton();
|
||||
|
||||
// Button styling
|
||||
if (_groupedAccessLevels.Count > 1)
|
||||
{
|
||||
if (AccessGroupList.ChildCount == 0)
|
||||
accessGroupButton.AddStyleClass(StyleBase.ButtonOpenLeft);
|
||||
else if (_groupedAccessLevels.Count > 1 && AccessGroupList.ChildCount == (_groupedAccessLevels.Count - 1))
|
||||
accessGroupButton.AddStyleClass(StyleBase.ButtonOpenRight);
|
||||
else
|
||||
accessGroupButton.AddStyleClass(StyleBase.ButtonOpenBoth);
|
||||
}
|
||||
|
||||
accessGroupButton.Pressed = _accessGroupTabIndex == orderedAccessGroups.IndexOf(accessGroup);
|
||||
|
||||
// Label text and styling
|
||||
if (_labelStyleClass != null)
|
||||
accessGroupButton.Label.SetOnlyStyleClass(_labelStyleClass);
|
||||
|
||||
var accessLevelPrototypes = _groupedAccessLevels[accessGroup];
|
||||
var prefix = accessLevelPrototypes.All(x => _activeAccessLevels.Contains(x))
|
||||
? "»"
|
||||
: accessLevelPrototypes.Any(x => _activeAccessLevels.Contains(x))
|
||||
? "›"
|
||||
: " ";
|
||||
|
||||
var text = Loc.GetString(
|
||||
"turret-controls-window-access-group-label",
|
||||
("prefix", prefix),
|
||||
("label", accessGroup.GetAccessGroupName())
|
||||
);
|
||||
|
||||
accessGroupButton.Text = text;
|
||||
|
||||
// Button events
|
||||
accessGroupButton.OnPressed += _ => OnAccessGroupChanged(accessGroupButton.GetPositionInParent());
|
||||
|
||||
AccessGroupList.AddChild(accessGroupButton);
|
||||
}
|
||||
|
||||
// Adjust the current tab index so it remains in range
|
||||
if (_accessGroupTabIndex >= _groupedAccessLevels.Count)
|
||||
_accessGroupTabIndex = _groupedAccessLevels.Count - 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds the checkbox list for the access level controls.
|
||||
/// </summary>
|
||||
public void RebuildAccessLevelsControls()
|
||||
{
|
||||
AccessLevelChecklist.DisposeAllChildren();
|
||||
_accessLevelEntries.Clear();
|
||||
|
||||
// No access level prototypes were assigned to any of the access level groups
|
||||
// Either turret controller has no assigned access levels, or their names were invalid
|
||||
if (_groupedAccessLevels.Count == 0)
|
||||
return;
|
||||
|
||||
// Reorder the access groups alphabetically
|
||||
var orderedAccessGroups = _groupedAccessLevels.Keys.OrderBy(x => x.GetAccessGroupName()).ToList();
|
||||
|
||||
// Get the access levels associated with the current tab
|
||||
var selectedAccessGroupTabProto = orderedAccessGroups[_accessGroupTabIndex];
|
||||
_accessLevelsForTab = _groupedAccessLevels[selectedAccessGroupTabProto];
|
||||
_accessLevelsForTab = _accessLevelsForTab.OrderBy(x => x.GetAccessLevelName()).ToList();
|
||||
|
||||
// Add an 'all' checkbox as the first child of the list if it has more than one access level
|
||||
// Toggling this checkbox on will mark all other boxes below it on/off
|
||||
var allCheckBox = CreateAccessLevelCheckbox();
|
||||
allCheckBox.Text = Loc.GetString("turret-controls-window-all-checkbox");
|
||||
|
||||
if (_labelStyleClass != null)
|
||||
allCheckBox.Label.SetOnlyStyleClass(_labelStyleClass);
|
||||
|
||||
// Add the 'all' checkbox events
|
||||
allCheckBox.OnPressed += args =>
|
||||
{
|
||||
SetCheckBoxPressedState(_accessLevelEntries, allCheckBox.Pressed);
|
||||
|
||||
var accessLevels = new HashSet<ProtoId<AccessLevelPrototype>>();
|
||||
|
||||
foreach (var accessLevel in _accessLevelsForTab)
|
||||
{
|
||||
accessLevels.Add(accessLevel);
|
||||
}
|
||||
|
||||
OnAccessLevelsChangedEvent?.Invoke(accessLevels, allCheckBox.Pressed);
|
||||
};
|
||||
|
||||
AccessLevelChecklist.AddChild(allCheckBox);
|
||||
|
||||
// Hide the 'all' checkbox if the tab has only one access level
|
||||
var allCheckBoxVisible = _accessLevelsForTab.Count > 1;
|
||||
|
||||
allCheckBox.Visible = allCheckBoxVisible;
|
||||
allCheckBox.Disabled = !_canInteract;
|
||||
|
||||
// Add any remaining missing access level buttons to the UI
|
||||
foreach (var accessLevel in _accessLevelsForTab)
|
||||
{
|
||||
// Create the entry
|
||||
var accessLevelEntry = new AccessLevelEntry(_isMonotone);
|
||||
|
||||
accessLevelEntry.AccessLevel = accessLevel;
|
||||
accessLevelEntry.CheckBox.Text = accessLevel.GetAccessLevelName();
|
||||
accessLevelEntry.CheckBox.Pressed = _activeAccessLevels.Contains(accessLevel);
|
||||
accessLevelEntry.CheckBox.Disabled = !_canInteract;
|
||||
|
||||
if (_labelStyleClass != null)
|
||||
accessLevelEntry.CheckBox.Label.SetOnlyStyleClass(_labelStyleClass);
|
||||
|
||||
// Set the checkbox linkage lines
|
||||
var isEndOfList = _accessLevelsForTab.IndexOf(accessLevel) == (_accessLevelsForTab.Count - 1);
|
||||
|
||||
var lines = new List<(Vector2, Vector2)>
|
||||
{
|
||||
(new Vector2(0.5f, 0f), new Vector2(0.5f, isEndOfList ? 0.5f : 1f)),
|
||||
(new Vector2(0.5f, 0.5f), new Vector2(1f, 0.5f)),
|
||||
};
|
||||
|
||||
accessLevelEntry.UpdateCheckBoxLink(lines);
|
||||
accessLevelEntry.CheckBoxLink.Visible = allCheckBoxVisible;
|
||||
accessLevelEntry.CheckBoxLink.Modulate = !_canInteract ? Color.Gray : Color.White;
|
||||
|
||||
// Add checkbox events
|
||||
accessLevelEntry.CheckBox.OnPressed += args =>
|
||||
{
|
||||
// If the checkbox and its siblings are checked, check the 'all' checkbox too
|
||||
allCheckBox.Pressed = AreAllCheckBoxesPressed(_accessLevelEntries.Select(x => x.CheckBox));
|
||||
|
||||
OnAccessLevelsChangedEvent?.Invoke([accessLevelEntry.AccessLevel], accessLevelEntry.CheckBox.Pressed);
|
||||
};
|
||||
|
||||
AccessLevelChecklist.AddChild(accessLevelEntry);
|
||||
_accessLevelEntries.Add(accessLevelEntry);
|
||||
}
|
||||
|
||||
// Press the 'all' checkbox if all others are pressed
|
||||
allCheckBox.Pressed = AreAllCheckBoxesPressed(_accessLevelEntries.Select(x => x.CheckBox));
|
||||
}
|
||||
|
||||
private bool AreAllCheckBoxesPressed(IEnumerable<CheckBox> checkBoxes)
|
||||
{
|
||||
foreach (var checkBox in checkBoxes)
|
||||
{
|
||||
if (!checkBox.Pressed)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetCheckBoxPressedState(List<AccessLevelEntry> accessLevelEntries, bool pressed)
|
||||
{
|
||||
foreach (var accessLevelEntry in accessLevelEntries)
|
||||
{
|
||||
accessLevelEntry.CheckBox.Pressed = pressed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Provides the UI with a list of access groups using which list of tabs should be populated.
|
||||
/// </summary>
|
||||
public void SetAccessGroups(HashSet<ProtoId<AccessGroupPrototype>> accessGroups)
|
||||
{
|
||||
_accessGroups = accessGroups;
|
||||
|
||||
ArrangeAccessControls();
|
||||
|
||||
if (TryRebuildAccessGroupControls())
|
||||
RebuildAccessLevelsControls();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the UI with a list of access levels with which it can populate the currently selected tab.
|
||||
/// </summary>
|
||||
public void SetAccessLevels(HashSet<ProtoId<AccessLevelPrototype>> accessLevels)
|
||||
{
|
||||
_accessLevels = accessLevels;
|
||||
|
||||
ArrangeAccessControls();
|
||||
|
||||
if (TryRebuildAccessGroupControls())
|
||||
RebuildAccessLevelsControls();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets which access level checkboxes should be marked on the UI.
|
||||
/// </summary>
|
||||
public void SetActiveAccessLevels(HashSet<ProtoId<AccessLevelPrototype>> activeAccessLevels)
|
||||
{
|
||||
_activeAccessLevels = activeAccessLevels;
|
||||
|
||||
if (TryRebuildAccessGroupControls())
|
||||
RebuildAccessLevelsControls();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether the local player can interact with the checkboxes.
|
||||
/// </summary>
|
||||
public void SetLocalPlayerAccessibility(bool canInteract)
|
||||
{
|
||||
_canInteract = canInteract;
|
||||
|
||||
if (TryRebuildAccessGroupControls())
|
||||
RebuildAccessLevelsControls();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether the UI should use monotone buttons and checkboxes.
|
||||
/// </summary>
|
||||
public void SetMonotone(bool monotone)
|
||||
{
|
||||
_isMonotone = monotone;
|
||||
|
||||
if (TryRebuildAccessGroupControls())
|
||||
RebuildAccessLevelsControls();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the specified style to the labels on the UI buttons and checkboxes.
|
||||
/// </summary>
|
||||
public void SetLabelStyleClass(string? styleClass)
|
||||
{
|
||||
_labelStyleClass = styleClass;
|
||||
|
||||
if (TryRebuildAccessGroupControls())
|
||||
RebuildAccessLevelsControls();
|
||||
}
|
||||
|
||||
private void OnAccessGroupChanged(int newTabIndex)
|
||||
{
|
||||
if (newTabIndex == _accessGroupTabIndex)
|
||||
return;
|
||||
|
||||
_accessGroupTabIndex = newTabIndex;
|
||||
|
||||
if (TryRebuildAccessGroupControls())
|
||||
RebuildAccessLevelsControls();
|
||||
}
|
||||
|
||||
private Button CreateAccessGroupButton()
|
||||
{
|
||||
var button = _isMonotone ? new MonotoneButton() : new Button();
|
||||
|
||||
button.ToggleMode = true;
|
||||
button.Group = _accessGroupsButtons;
|
||||
button.Label.HorizontalAlignment = HAlignment.Left;
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private CheckBox CreateAccessLevelCheckbox()
|
||||
{
|
||||
var checkbox = _isMonotone ? new MonotoneCheckBox() : new CheckBox();
|
||||
|
||||
checkbox.Margin = new Thickness(0, 0, 0, 3);
|
||||
checkbox.ToggleMode = true;
|
||||
checkbox.ReservesSpace = false;
|
||||
|
||||
return checkbox;
|
||||
}
|
||||
|
||||
private sealed class AccessLevelEntry : BoxContainer
|
||||
{
|
||||
public ProtoId<AccessLevelPrototype> AccessLevel;
|
||||
public readonly CheckBox CheckBox;
|
||||
public readonly LineRenderer CheckBoxLink;
|
||||
|
||||
public AccessLevelEntry(bool monotone)
|
||||
{
|
||||
HorizontalExpand = true;
|
||||
|
||||
CheckBoxLink = new LineRenderer
|
||||
{
|
||||
SetWidth = 22,
|
||||
VerticalExpand = true,
|
||||
Margin = new Thickness(0, -1),
|
||||
ReservesSpace = false,
|
||||
};
|
||||
|
||||
AddChild(CheckBoxLink);
|
||||
|
||||
CheckBox = monotone ? new MonotoneCheckBox() : new CheckBox();
|
||||
CheckBox.ToggleMode = true;
|
||||
CheckBox.Margin = new Thickness(0f, 0f, 0f, 3f);
|
||||
|
||||
AddChild(CheckBox);
|
||||
}
|
||||
|
||||
public void UpdateCheckBoxLink(List<(Vector2, Vector2)> lines)
|
||||
{
|
||||
CheckBoxLink.Lines = lines;
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class LineRenderer : Control
|
||||
{
|
||||
/// <summary>
|
||||
/// List of lines to render (their start and end x-y coordinates).
|
||||
/// Position (0,0) is the top left corner of the control and
|
||||
/// position (1,1) is the bottom right corner.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The color of the lines is inherited from the control.
|
||||
/// </remarks>
|
||||
public List<(Vector2, Vector2)> Lines;
|
||||
|
||||
public LineRenderer()
|
||||
{
|
||||
Lines = new List<(Vector2, Vector2)>();
|
||||
}
|
||||
|
||||
public LineRenderer(List<(Vector2, Vector2)> lines)
|
||||
{
|
||||
Lines = lines;
|
||||
}
|
||||
|
||||
protected override void Draw(DrawingHandleScreen handle)
|
||||
{
|
||||
foreach (var line in Lines)
|
||||
{
|
||||
var start = PixelPosition +
|
||||
new Vector2(PixelWidth * line.Item1.X, PixelHeight * line.Item1.Y);
|
||||
|
||||
var end = PixelPosition +
|
||||
new Vector2(PixelWidth * line.Item2.X, PixelHeight * line.Item2.Y);
|
||||
|
||||
handle.DrawLine(start, end, ActualModulateSelf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
using Content.Shared.Access;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.CrewManifest;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Prototypes;
|
||||
using static Content.Shared.Access.Components.IdCardConsoleComponent;
|
||||
|
||||
|
|
@ -11,13 +13,21 @@ namespace Content.Client.Access.UI
|
|||
public sealed class IdCardConsoleBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
|
||||
private readonly SharedIdCardConsoleSystem _idCardConsoleSystem = default!;
|
||||
|
||||
private IdCardConsoleWindow? _window;
|
||||
|
||||
// CCVar.
|
||||
private int _maxNameLength;
|
||||
private int _maxIdJobLength;
|
||||
|
||||
public IdCardConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
_idCardConsoleSystem = EntMan.System<SharedIdCardConsoleSystem>();
|
||||
|
||||
_maxNameLength =_cfgManager.GetCVar(CCVars.MaxNameLength);
|
||||
_maxIdJobLength = _cfgManager.GetCVar(CCVars.MaxIdJobLength);
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
|
|
@ -66,11 +76,11 @@ namespace Content.Client.Access.UI
|
|||
|
||||
public void SubmitData(string newFullName, string newJobTitle, List<ProtoId<AccessLevelPrototype>> newAccessList, string newJobPrototype)
|
||||
{
|
||||
if (newFullName.Length > MaxFullNameLength)
|
||||
newFullName = newFullName[..MaxFullNameLength];
|
||||
if (newFullName.Length > _maxNameLength)
|
||||
newFullName = newFullName[.._maxNameLength];
|
||||
|
||||
if (newJobTitle.Length > MaxJobTitleLength)
|
||||
newJobTitle = newJobTitle[..MaxJobTitleLength];
|
||||
if (newJobTitle.Length > _maxIdJobLength)
|
||||
newJobTitle = newJobTitle[.._maxIdJobLength];
|
||||
|
||||
SendMessage(new WriteToTargetIdMessage(
|
||||
newFullName,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
using System.Linq;
|
||||
using Content.Shared.Access;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Prototypes;
|
||||
using static Content.Shared.Access.Components.IdCardConsoleComponent;
|
||||
|
||||
|
|
@ -14,12 +16,17 @@ namespace Content.Client.Access.UI
|
|||
[GenerateTypedNameReferences]
|
||||
public sealed partial class IdCardConsoleWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
private readonly ISawmill _logMill = default!;
|
||||
|
||||
private readonly IdCardConsoleBoundUserInterface _owner;
|
||||
|
||||
// CCVar.
|
||||
private int _maxNameLength;
|
||||
private int _maxIdJobLength;
|
||||
|
||||
private AccessLevelControl _accessButtons = new();
|
||||
private readonly List<string> _jobPrototypeIds = new();
|
||||
|
||||
|
|
@ -39,7 +46,11 @@ namespace Content.Client.Access.UI
|
|||
|
||||
_owner = owner;
|
||||
|
||||
_maxNameLength = _cfgManager.GetCVar(CCVars.MaxNameLength);
|
||||
_maxIdJobLength = _cfgManager.GetCVar(CCVars.MaxIdJobLength);
|
||||
|
||||
FullNameLineEdit.OnTextEntered += _ => SubmitData();
|
||||
FullNameLineEdit.IsValid = s => s.Length <= _maxNameLength;
|
||||
FullNameLineEdit.OnTextChanged += _ =>
|
||||
{
|
||||
FullNameSaveButton.Disabled = FullNameSaveButton.Text == _lastFullName;
|
||||
|
|
@ -47,6 +58,7 @@ namespace Content.Client.Access.UI
|
|||
FullNameSaveButton.OnPressed += _ => SubmitData();
|
||||
|
||||
JobTitleLineEdit.OnTextEntered += _ => SubmitData();
|
||||
JobTitleLineEdit.IsValid = s => s.Length <= _maxIdJobLength;
|
||||
JobTitleLineEdit.OnTextChanged += _ =>
|
||||
{
|
||||
JobTitleSaveButton.Disabled = JobTitleLineEdit.Text == _lastJobTitle;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ namespace Content.Client.Administration.Systems;
|
|||
|
||||
public sealed class KillSignSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<KillSignComponent, ComponentStartup>(KillSignAdded);
|
||||
|
|
@ -18,10 +20,10 @@ public sealed class KillSignSystem : EntitySystem
|
|||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
if (!sprite.LayerMapTryGet(KillSignKey.Key, out var layer))
|
||||
if (!_sprite.LayerMapTryGet((uid, sprite), KillSignKey.Key, out var layer, false))
|
||||
return;
|
||||
|
||||
sprite.RemoveLayer(layer);
|
||||
_sprite.RemoveLayer((uid, sprite), layer);
|
||||
}
|
||||
|
||||
private void KillSignAdded(EntityUid uid, KillSignComponent component, ComponentStartup args)
|
||||
|
|
@ -29,15 +31,15 @@ public sealed class KillSignSystem : EntitySystem
|
|||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
if (sprite.LayerMapTryGet(KillSignKey.Key, out var _))
|
||||
if (_sprite.LayerMapTryGet((uid, sprite), KillSignKey.Key, out var _, false))
|
||||
return;
|
||||
|
||||
var adj = sprite.Bounds.Height / 2 + ((1.0f/32) * 6.0f);
|
||||
var adj = _sprite.GetLocalBounds((uid, sprite)).Height / 2 + ((1.0f / 32) * 6.0f);
|
||||
|
||||
var layer = sprite.AddLayer(new SpriteSpecifier.Rsi(new ResPath("Objects/Misc/killsign.rsi"), "sign"));
|
||||
sprite.LayerMapSet(KillSignKey.Key, layer);
|
||||
var layer = _sprite.AddLayer((uid, sprite), new SpriteSpecifier.Rsi(new ResPath("Objects/Misc/killsign.rsi"), "sign"));
|
||||
_sprite.LayerMapSet((uid, sprite), KillSignKey.Key, layer);
|
||||
|
||||
sprite.LayerSetOffset(layer, new Vector2(0.0f, adj));
|
||||
_sprite.LayerSetOffset((uid, sprite), layer, new Vector2(0.0f, adj));
|
||||
sprite.LayerSetShader(layer, "unshaded");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ namespace Content.Client.Administration.UI.SpawnExplosion;
|
|||
public sealed partial class SpawnExplosionWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IClientConsoleHost _conHost = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
private readonly SharedMapSystem _mapSystem;
|
||||
private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
private readonly SpawnExplosionEui _eui;
|
||||
|
|
@ -38,6 +38,7 @@ public sealed partial class SpawnExplosionWindow : DefaultWindow
|
|||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
_mapSystem = _entMan.System<SharedMapSystem>();
|
||||
_transform = _entMan.System<TransformSystem>();
|
||||
_eui = eui;
|
||||
|
||||
|
|
@ -87,7 +88,7 @@ public sealed partial class SpawnExplosionWindow : DefaultWindow
|
|||
{
|
||||
_mapData.Clear();
|
||||
MapOptions.Clear();
|
||||
foreach (var map in _mapManager.GetAllMapIds())
|
||||
foreach (var map in _mapSystem.GetAllMapIds())
|
||||
{
|
||||
_mapData.Add(map);
|
||||
MapOptions.AddItem(map.ToString());
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ namespace Content.Client.Administration.UI.Tabs.AdminbusTab
|
|||
[UsedImplicitly]
|
||||
public sealed partial class LoadBlueprintsWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
public LoadBlueprintsWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
|
@ -21,9 +24,9 @@ namespace Content.Client.Administration.UI.Tabs.AdminbusTab
|
|||
|
||||
protected override void EnteredTree()
|
||||
{
|
||||
var mapManager = IoCManager.Resolve<IMapManager>();
|
||||
var mapSystem = _entityManager.System<SharedMapSystem>();
|
||||
|
||||
foreach (var mapId in mapManager.GetAllMapIds())
|
||||
foreach (var mapId in mapSystem.GetAllMapIds())
|
||||
{
|
||||
MapOptions.AddItem(mapId.ToString(), (int) mapId);
|
||||
}
|
||||
|
|
@ -39,21 +42,19 @@ namespace Content.Client.Administration.UI.Tabs.AdminbusTab
|
|||
|
||||
private void Reset()
|
||||
{
|
||||
var entManager = IoCManager.Resolve<IEntityManager>();
|
||||
var xformSystem = entManager.System<SharedTransformSystem>();
|
||||
var playerManager = IoCManager.Resolve<IPlayerManager>();
|
||||
var player = playerManager.LocalEntity;
|
||||
var xformSystem = _entityManager.System<SharedTransformSystem>();
|
||||
var player = _playerManager.LocalEntity;
|
||||
|
||||
var currentMap = MapId.Nullspace;
|
||||
var position = Vector2.Zero;
|
||||
var rotation = Angle.Zero;
|
||||
|
||||
if (entManager.TryGetComponent<TransformComponent>(player, out var xform))
|
||||
if (_entityManager.TryGetComponent<TransformComponent>(player, out var xform))
|
||||
{
|
||||
currentMap = xform.MapID;
|
||||
position = xformSystem.GetWorldPosition(xform);
|
||||
|
||||
if (entManager.TryGetComponent<TransformComponent>(xform.GridUid, out var gridXform))
|
||||
if (_entityManager.TryGetComponent<TransformComponent>(xform.GridUid, out var gridXform))
|
||||
{
|
||||
rotation = xformSystem.GetWorldRotation(gridXform);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<Control
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Margin="4"
|
||||
MinSize="50 50">
|
||||
<GridContainer
|
||||
Columns="3">
|
||||
<cc:CommandButton Command="startround" Text="{Loc administration-ui-round-tab-start-round}" />
|
||||
<cc:CommandButton Command="endround" Text="{Loc administration-ui-round-tab-end-round}" />
|
||||
<cc:CommandButton Command="restartround" Text="{Loc administration-ui-round-tab-restart-round}" />
|
||||
<cc:CommandButton Command="restartroundnow" Text="{Loc administration-ui-round-tab-restart-round-now}" />
|
||||
<controls:ConfirmButton Name="StartRound" Text="{Loc administration-ui-round-tab-start-round}" />
|
||||
<controls:ConfirmButton Name="EndRound" Text="{Loc administration-ui-round-tab-end-round}" />
|
||||
<controls:ConfirmButton Name="RestartRound" Text="{Loc administration-ui-round-tab-restart-round}" />
|
||||
<controls:ConfirmButton Name="RestartRoundNow" Text="{Loc administration-ui-round-tab-restart-round-now}" />
|
||||
</GridContainer>
|
||||
</Control>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,24 @@
|
|||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Console;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.Administration.UI.Tabs
|
||||
{
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class RoundTab : Control
|
||||
{
|
||||
[Dependency] private readonly IClientConsoleHost _console = default!;
|
||||
|
||||
public RoundTab()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
StartRound.OnPressed += _ => _console.ExecuteCommand("startround");
|
||||
EndRound.OnPressed += _ => _console.ExecuteCommand("endround");
|
||||
RestartRound.OnPressed += _ => _console.ExecuteCommand("restartround");
|
||||
RestartRoundNow.OnPressed += _ => _console.ExecuteCommand("restartroundnow");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ namespace Content.Client.AlertLevel;
|
|||
|
||||
public sealed class AlertLevelDisplaySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
|
@ -21,26 +23,26 @@ public sealed class AlertLevelDisplaySystem : EntitySystem
|
|||
{
|
||||
return;
|
||||
}
|
||||
var layer = args.Sprite.LayerMapReserveBlank(AlertLevelDisplay.Layer);
|
||||
var layer = _sprite.LayerMapReserve((uid, args.Sprite), AlertLevelDisplay.Layer);
|
||||
|
||||
if (args.AppearanceData.TryGetValue(AlertLevelDisplay.Powered, out var poweredObject))
|
||||
{
|
||||
args.Sprite.LayerSetVisible(layer, poweredObject is true);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, poweredObject is true);
|
||||
}
|
||||
|
||||
if (!args.AppearanceData.TryGetValue(AlertLevelDisplay.CurrentLevel, out var level))
|
||||
{
|
||||
args.Sprite.LayerSetState(layer, alertLevelDisplay.AlertVisuals.Values.First());
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, alertLevelDisplay.AlertVisuals.Values.First());
|
||||
return;
|
||||
}
|
||||
|
||||
if (alertLevelDisplay.AlertVisuals.TryGetValue((string) level, out var visual))
|
||||
if (alertLevelDisplay.AlertVisuals.TryGetValue((string)level, out var visual))
|
||||
{
|
||||
args.Sprite.LayerSetState(layer, visual);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, visual);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Sprite.LayerSetState(layer, alertLevelDisplay.AlertVisuals.Values.First());
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, alertLevelDisplay.AlertVisuals.Values.First());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ public sealed class EntityPickupAnimationSystem : EntitySystem
|
|||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _animations = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
|
||||
public override void Initialize()
|
||||
|
|
@ -56,8 +57,8 @@ public sealed class EntityPickupAnimationSystem : EntitySystem
|
|||
}
|
||||
|
||||
var sprite = Comp<SpriteComponent>(animatableClone);
|
||||
sprite.CopyFrom(sprite0);
|
||||
sprite.Visible = true;
|
||||
_sprite.CopySprite((uid, sprite0), (animatableClone, sprite));
|
||||
_sprite.SetVisible((animatableClone, sprite), true);
|
||||
|
||||
var animations = Comp<AnimationPlayerComponent>(animatableClone);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ public sealed class AnomalySystem : SharedAnomalySystem
|
|||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly FloatingVisualizerSystem _floating = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
|
|
@ -49,12 +50,12 @@ public sealed class AnomalySystem : SharedAnomalySystem
|
|||
if (HasComp<AnomalySupercriticalComponent>(uid))
|
||||
pulsing = true;
|
||||
|
||||
if (!sprite.LayerMapTryGet(AnomalyVisualLayers.Base, out var layer) ||
|
||||
!sprite.LayerMapTryGet(AnomalyVisualLayers.Animated, out var animatedLayer))
|
||||
if (!_sprite.LayerMapTryGet((uid, sprite), AnomalyVisualLayers.Base, out var layer, false) ||
|
||||
!_sprite.LayerMapTryGet((uid, sprite), AnomalyVisualLayers.Animated, out var animatedLayer, false))
|
||||
return;
|
||||
|
||||
sprite.LayerSetVisible(layer, !pulsing);
|
||||
sprite.LayerSetVisible(animatedLayer, pulsing);
|
||||
_sprite.LayerSetVisible((uid, sprite), layer, !pulsing);
|
||||
_sprite.LayerSetVisible((uid, sprite), animatedLayer, pulsing);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
|
|
@ -63,16 +64,16 @@ public sealed class AnomalySystem : SharedAnomalySystem
|
|||
|
||||
var query = EntityQueryEnumerator<AnomalySupercriticalComponent, SpriteComponent>();
|
||||
|
||||
while (query.MoveNext(out var super, out var sprite))
|
||||
while (query.MoveNext(out var uid, out var super, out var sprite))
|
||||
{
|
||||
var completion = 1f - (float) ((super.EndTime - _timing.CurTime) / super.SupercriticalDuration);
|
||||
var completion = 1f - (float)((super.EndTime - _timing.CurTime) / super.SupercriticalDuration);
|
||||
var scale = completion * (super.MaxScaleAmount - 1f) + 1f;
|
||||
sprite.Scale = new Vector2(scale, scale);
|
||||
_sprite.SetScale((uid, sprite), new Vector2(scale, scale));
|
||||
|
||||
var transparency = (byte) (65 * (1f - completion) + 190);
|
||||
var transparency = (byte)(65 * (1f - completion) + 190);
|
||||
if (transparency < sprite.Color.AByte)
|
||||
{
|
||||
sprite.Color = sprite.Color.WithAlpha(transparency);
|
||||
_sprite.SetColor((uid, sprite), sprite.Color.WithAlpha(transparency));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -82,7 +83,7 @@ public sealed class AnomalySystem : SharedAnomalySystem
|
|||
if (!TryComp<SpriteComponent>(ent, out var sprite))
|
||||
return;
|
||||
|
||||
sprite.Scale = Vector2.One;
|
||||
sprite.Color = sprite.Color.WithAlpha(1f);
|
||||
_sprite.SetScale((ent.Owner, sprite), Vector2.One);
|
||||
_sprite.SetColor((ent.Owner, sprite), sprite.Color.WithAlpha(1f));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ namespace Content.Client.Anomaly.Effects;
|
|||
|
||||
public sealed class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<InnerBodyAnomalyComponent, AfterAutoHandleStateEvent>(OnAfterHandleState);
|
||||
|
|
@ -21,21 +23,20 @@ public sealed class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem
|
|||
if (ent.Comp.FallbackSprite is null)
|
||||
return;
|
||||
|
||||
if (!sprite.LayerMapTryGet(ent.Comp.LayerMap, out var index))
|
||||
index = sprite.LayerMapReserveBlank(ent.Comp.LayerMap);
|
||||
var index = _sprite.LayerMapReserve((ent.Owner, sprite), ent.Comp.LayerMap);
|
||||
|
||||
if (TryComp<BodyComponent>(ent, out var body) &&
|
||||
body.Prototype is not null &&
|
||||
ent.Comp.SpeciesSprites.TryGetValue(body.Prototype.Value, out var speciesSprite))
|
||||
{
|
||||
sprite.LayerSetSprite(index, speciesSprite);
|
||||
_sprite.LayerSetSprite((ent.Owner, sprite), index, speciesSprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetSprite(index, ent.Comp.FallbackSprite);
|
||||
_sprite.LayerSetSprite((ent.Owner, sprite), index, ent.Comp.FallbackSprite);
|
||||
}
|
||||
|
||||
sprite.LayerSetVisible(index, true);
|
||||
_sprite.LayerSetVisible((ent.Owner, sprite), index, true);
|
||||
sprite.LayerSetShader(index, "unshaded");
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +45,7 @@ public sealed class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem
|
|||
if (!TryComp<SpriteComponent>(ent, out var sprite))
|
||||
return;
|
||||
|
||||
var index = sprite.LayerMapGet(ent.Comp.LayerMap);
|
||||
sprite.LayerSetVisible(index, false);
|
||||
var index = _sprite.LayerMapGet((ent.Owner, sprite), ent.Comp.LayerMap);
|
||||
_sprite.LayerSetVisible((ent.Owner, sprite), index, false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace Content.Client.Atmos.EntitySystems;
|
|||
public sealed class AtmosPipeAppearanceSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -25,21 +26,22 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem
|
|||
if (!TryComp(uid, out SpriteComponent? sprite))
|
||||
return;
|
||||
|
||||
foreach (PipeConnectionLayer layerKey in Enum.GetValues(typeof(PipeConnectionLayer)))
|
||||
foreach (var layerKey in Enum.GetValues<PipeConnectionLayer>())
|
||||
{
|
||||
sprite.LayerMapReserveBlank(layerKey);
|
||||
var layer = sprite.LayerMapGet(layerKey);
|
||||
sprite.LayerSetRSI(layer, component.Sprite.RsiPath);
|
||||
sprite.LayerSetState(layer, component.Sprite.RsiState);
|
||||
sprite.LayerSetDirOffset(layer, ToOffset(layerKey));
|
||||
var layer = _sprite.LayerMapReserve((uid, sprite), layerKey);
|
||||
_sprite.LayerSetRsi((uid, sprite), layer, component.Sprite.RsiPath);
|
||||
_sprite.LayerSetRsiState((uid, sprite), layer, component.Sprite.RsiState);
|
||||
_sprite.LayerSetDirOffset((uid, sprite), layer, ToOffset(layerKey));
|
||||
}
|
||||
}
|
||||
|
||||
private void HideAllPipeConnection(SpriteComponent sprite)
|
||||
private void HideAllPipeConnection(Entity<SpriteComponent> entity)
|
||||
{
|
||||
foreach (PipeConnectionLayer layerKey in Enum.GetValues(typeof(PipeConnectionLayer)))
|
||||
var sprite = entity.Comp;
|
||||
|
||||
foreach (var layerKey in Enum.GetValues<PipeConnectionLayer>())
|
||||
{
|
||||
if (!sprite.LayerMapTryGet(layerKey, out var key))
|
||||
if (!_sprite.LayerMapTryGet(entity.AsNullable(), layerKey, out var key, false))
|
||||
continue;
|
||||
|
||||
var layer = sprite[key];
|
||||
|
|
@ -61,7 +63,7 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem
|
|||
|
||||
if (!_appearance.TryGetData<PipeDirection>(uid, PipeVisuals.VisualState, out var worldConnectedDirections, args.Component))
|
||||
{
|
||||
HideAllPipeConnection(args.Sprite);
|
||||
HideAllPipeConnection((uid, args.Sprite));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -71,13 +73,13 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem
|
|||
// transform connected directions to local-coordinates
|
||||
var connectedDirections = worldConnectedDirections.RotatePipeDirection(-Transform(uid).LocalRotation);
|
||||
|
||||
foreach (PipeConnectionLayer layerKey in Enum.GetValues(typeof(PipeConnectionLayer)))
|
||||
foreach (var layerKey in Enum.GetValues<PipeConnectionLayer>())
|
||||
{
|
||||
if (!args.Sprite.LayerMapTryGet(layerKey, out var key))
|
||||
if (!_sprite.LayerMapTryGet((uid, args.Sprite), layerKey, out var key, false))
|
||||
continue;
|
||||
|
||||
var layer = args.Sprite[key];
|
||||
var dir = (PipeDirection) layerKey;
|
||||
var dir = (PipeDirection)layerKey;
|
||||
var visible = connectedDirections.HasDirection(dir);
|
||||
|
||||
layer.Visible &= visible;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using Content.Client.Atmos.Components;
|
|||
using Content.Shared.Atmos;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Atmos.EntitySystems;
|
||||
|
||||
|
|
@ -31,9 +32,9 @@ public sealed class FireVisualizerSystem : VisualizerSystem<FireVisualsComponent
|
|||
// Need LayerMapTryGet because Init fails if there's no existing sprite / appearancecomp
|
||||
// which means in some setups (most frequently no AppearanceComp) the layer never exists.
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite) &&
|
||||
sprite.LayerMapTryGet(FireVisualLayers.Fire, out var layer))
|
||||
SpriteSystem.LayerMapTryGet((uid, sprite), FireVisualLayers.Fire, out var layer, false))
|
||||
{
|
||||
sprite.RemoveLayer(layer);
|
||||
SpriteSystem.RemoveLayer((uid, sprite), layer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,11 +43,11 @@ public sealed class FireVisualizerSystem : VisualizerSystem<FireVisualsComponent
|
|||
if (!TryComp<SpriteComponent>(uid, out var sprite) || !TryComp(uid, out AppearanceComponent? appearance))
|
||||
return;
|
||||
|
||||
sprite.LayerMapReserveBlank(FireVisualLayers.Fire);
|
||||
sprite.LayerSetVisible(FireVisualLayers.Fire, false);
|
||||
SpriteSystem.LayerMapReserve((uid, sprite), FireVisualLayers.Fire);
|
||||
SpriteSystem.LayerSetVisible((uid, sprite), FireVisualLayers.Fire, false);
|
||||
sprite.LayerSetShader(FireVisualLayers.Fire, "unshaded");
|
||||
if (component.Sprite != null)
|
||||
sprite.LayerSetRSI(FireVisualLayers.Fire, component.Sprite);
|
||||
SpriteSystem.LayerSetRsi((uid, sprite), FireVisualLayers.Fire, new ResPath(component.Sprite));
|
||||
|
||||
UpdateAppearance(uid, component, sprite, appearance);
|
||||
}
|
||||
|
|
@ -59,12 +60,12 @@ public sealed class FireVisualizerSystem : VisualizerSystem<FireVisualsComponent
|
|||
|
||||
private void UpdateAppearance(EntityUid uid, FireVisualsComponent component, SpriteComponent sprite, AppearanceComponent appearance)
|
||||
{
|
||||
if (!sprite.LayerMapTryGet(FireVisualLayers.Fire, out var index))
|
||||
if (!SpriteSystem.LayerMapTryGet((uid, sprite), FireVisualLayers.Fire, out var index, false))
|
||||
return;
|
||||
|
||||
AppearanceSystem.TryGetData<bool>(uid, FireVisuals.OnFire, out var onFire, appearance);
|
||||
AppearanceSystem.TryGetData<float>(uid, FireVisuals.FireStacks, out var fireStacks, appearance);
|
||||
sprite.LayerSetVisible(index, onFire);
|
||||
SpriteSystem.LayerSetVisible((uid, sprite), index, onFire);
|
||||
|
||||
if (!onFire)
|
||||
{
|
||||
|
|
@ -78,9 +79,9 @@ public sealed class FireVisualizerSystem : VisualizerSystem<FireVisualsComponent
|
|||
}
|
||||
|
||||
if (fireStacks > component.FireStackAlternateState && !string.IsNullOrEmpty(component.AlternateState))
|
||||
sprite.LayerSetState(index, component.AlternateState);
|
||||
SpriteSystem.LayerSetRsiState((uid, sprite), index, component.AlternateState);
|
||||
else
|
||||
sprite.LayerSetState(index, component.NormalState);
|
||||
SpriteSystem.LayerSetRsiState((uid, sprite), index, component.NormalState);
|
||||
|
||||
component.LightEntity ??= Spawn(null, new EntityCoordinates(uid, default));
|
||||
var light = EnsureComp<PointLightComponent>(component.LightEntity.Value);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem<AtmosAlarmabl
|
|||
{
|
||||
protected override void OnAppearanceChange(EntityUid uid, AtmosAlarmableVisualsComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null || !args.Sprite.LayerMapTryGet(component.LayerMap, out var layer))
|
||||
if (args.Sprite == null || !SpriteSystem.LayerMapTryGet((uid, args.Sprite), component.LayerMap, out var layer, false))
|
||||
return;
|
||||
|
||||
if (!args.AppearanceData.TryGetValue(PowerDeviceVisuals.Powered, out var poweredObject) ||
|
||||
|
|
@ -22,8 +22,8 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem<AtmosAlarmabl
|
|||
{
|
||||
foreach (var visLayer in component.HideOnDepowered)
|
||||
{
|
||||
if (args.Sprite.LayerMapTryGet(visLayer, out var powerVisibilityLayer))
|
||||
args.Sprite.LayerSetVisible(powerVisibilityLayer, powered);
|
||||
if (SpriteSystem.LayerMapTryGet((uid, args.Sprite), visLayer, out var powerVisibilityLayer, false))
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), powerVisibilityLayer, powered);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -31,8 +31,8 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem<AtmosAlarmabl
|
|||
{
|
||||
foreach (var (setLayer, powerState) in component.SetOnDepowered)
|
||||
{
|
||||
if (args.Sprite.LayerMapTryGet(setLayer, out var setStateLayer))
|
||||
args.Sprite.LayerSetState(setStateLayer, new RSI.StateId(powerState));
|
||||
if (SpriteSystem.LayerMapTryGet((uid, args.Sprite), setLayer, out var setStateLayer, false))
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), setStateLayer, new RSI.StateId(powerState));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem<AtmosAlarmabl
|
|||
&& powered
|
||||
&& component.AlarmStates.TryGetValue(alarmType, out var state))
|
||||
{
|
||||
args.Sprite.LayerSetState(layer, new RSI.StateId(state));
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), layer, new RSI.StateId(state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,13 @@
|
|||
<!-- Mode buttons -->
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<Label Text="{Loc 'air-alarm-ui-window-mode-label'}" Margin="0 0 2 0" />
|
||||
<OptionButton Name="CModeButton" HorizontalExpand="True" />
|
||||
<Control HorizontalExpand="True">
|
||||
<OptionButton Name="CModeButton" />
|
||||
<ui:StripeBack Name="CModeSelectLocked">
|
||||
<RichTextLabel Text="{Loc 'air-alarm-ui-window-mode-select-locked-label'}"
|
||||
HorizontalAlignment="Center" />
|
||||
</ui:StripeBack>
|
||||
</Control>
|
||||
<CheckBox Name="AutoModeCheckBox" Text="{Loc 'air-alarm-ui-window-auto-mode-label'}" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ public sealed partial class AirAlarmWindow : FancyWindow
|
|||
{
|
||||
UpdateDeviceData(addr, dev);
|
||||
}
|
||||
_modes.Visible = !state.PanicWireCut;
|
||||
CModeSelectLocked.Visible = state.PanicWireCut;
|
||||
}
|
||||
|
||||
public void UpdateModeSelector(AirAlarmMode mode)
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public sealed partial class ScrubberControl : BoxContainer
|
|||
_data.PumpDirection = (ScrubberPumpDirection) args.Id;
|
||||
ScrubberDataChanged?.Invoke(_address, _data);
|
||||
};
|
||||
_pumpDirection.Disabled = data.AirAlarmPanicWireCut;
|
||||
|
||||
_copySettings.OnPressed += _ =>
|
||||
{
|
||||
|
|
@ -109,6 +110,7 @@ public sealed partial class ScrubberControl : BoxContainer
|
|||
|
||||
_data.PumpDirection = data.PumpDirection;
|
||||
_pumpDirection.Select((int) _data.PumpDirection);
|
||||
_pumpDirection.Disabled = data.AirAlarmPanicWireCut;
|
||||
|
||||
_data.VolumeRate = data.VolumeRate;
|
||||
_volumeRate.Value = _data.VolumeRate;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ namespace Content.Client.Atmos.Overlays
|
|||
{
|
||||
private readonly IEntityManager _entManager;
|
||||
private readonly IMapManager _mapManager;
|
||||
private readonly SharedMapSystem _mapSystem;
|
||||
private readonly SharedTransformSystem _xformSys;
|
||||
|
||||
public override OverlaySpace Space => OverlaySpace.WorldSpaceEntities | OverlaySpace.WorldSpaceBelowWorld;
|
||||
|
|
@ -51,6 +52,7 @@ namespace Content.Client.Atmos.Overlays
|
|||
{
|
||||
_entManager = entManager;
|
||||
_mapManager = IoCManager.Resolve<IMapManager>();
|
||||
_mapSystem = entManager.System<SharedMapSystem>();
|
||||
_xformSys = xformSys;
|
||||
_shader = protoMan.Index<ShaderPrototype>("unshaded").Instance();
|
||||
ZIndex = GasOverlayZIndex;
|
||||
|
|
@ -163,7 +165,7 @@ namespace Content.Client.Atmos.Overlays
|
|||
xformQuery,
|
||||
_xformSys);
|
||||
|
||||
var mapUid = _mapManager.GetMapEntityId(args.MapId);
|
||||
var mapUid = _mapSystem.GetMapOrInvalid(args.MapId);
|
||||
|
||||
if (_entManager.TryGetComponent<MapAtmosphereComponent>(mapUid, out var atmos))
|
||||
DrawMapOverlay(drawHandle, args, mapUid, atmos);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
using Content.Shared.Atmos.Piping.Binary.Systems;
|
||||
|
||||
namespace Content.Client.Atmos.Piping.Binary.Systems;
|
||||
|
||||
public sealed class GasValveSystem : SharedGasValveSystem
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using Content.Client.Atmos.UI;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Systems;
|
||||
|
||||
namespace Content.Client.Atmos.Piping.Unary.Systems;
|
||||
|
||||
public sealed class GasThermoMachineSystem : SharedGasThermoMachineSystem
|
||||
{
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<GasThermoMachineComponent, AfterAutoHandleStateEvent>(OnGasAfterState);
|
||||
}
|
||||
|
||||
private void OnGasAfterState(Entity<GasThermoMachineComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
DirtyUI(ent.Owner, ent.Comp);
|
||||
}
|
||||
|
||||
protected override void DirtyUI(EntityUid uid, GasThermoMachineComponent? thermoMachine, UserInterfaceComponent? ui = null)
|
||||
{
|
||||
if (_ui.TryGetOpenUi<GasThermomachineBoundUserInterface>(uid, ThermomachineUiKey.Key, out var bui))
|
||||
{
|
||||
bui.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
using Content.Shared.Atmos;
|
||||
using Content.Client.Power.EntitySystems;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Systems;
|
||||
using Content.Shared.Power.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
|
|
@ -36,6 +39,8 @@ namespace Content.Client.Atmos.UI
|
|||
|
||||
_window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed();
|
||||
_window.TemperatureSpinbox.OnValueChanged += _ => OnTemperatureChanged(_window.TemperatureSpinbox.Value);
|
||||
_window.Entity = Owner;
|
||||
Update();
|
||||
}
|
||||
|
||||
private void OnToggleStatusButtonPressed()
|
||||
|
|
@ -43,7 +48,7 @@ namespace Content.Client.Atmos.UI
|
|||
if (_window is null) return;
|
||||
|
||||
_window.SetActive(!_window.Active);
|
||||
SendMessage(new GasThermomachineToggleMessage());
|
||||
SendPredictedMessage(new GasThermomachineToggleMessage());
|
||||
}
|
||||
|
||||
private void OnTemperatureChanged(float value)
|
||||
|
|
@ -60,25 +65,32 @@ namespace Content.Client.Atmos.UI
|
|||
return;
|
||||
}
|
||||
|
||||
SendMessage(new GasThermomachineChangeTemperatureMessage(actual));
|
||||
SendPredictedMessage(new GasThermomachineChangeTemperatureMessage(actual));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the UI state based on server-sent info
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
public override void Update()
|
||||
{
|
||||
base.UpdateState(state);
|
||||
if (_window == null || state is not GasThermomachineBoundUserInterfaceState cast)
|
||||
if (_window == null || !EntMan.TryGetComponent(Owner, out GasThermoMachineComponent? thermo))
|
||||
return;
|
||||
|
||||
_minTemp = cast.MinTemperature;
|
||||
_maxTemp = cast.MaxTemperature;
|
||||
_isHeater = cast.IsHeater;
|
||||
var system = EntMan.System<SharedGasThermoMachineSystem>();
|
||||
_minTemp = thermo.MinTemperature;
|
||||
_maxTemp = thermo.MaxTemperature;
|
||||
_isHeater = system.IsHeater(thermo);
|
||||
|
||||
_window.SetTemperature(thermo.TargetTemperature);
|
||||
|
||||
var receiverSys = EntMan.System<PowerReceiverSystem>();
|
||||
SharedApcPowerReceiverComponent? receiver = null;
|
||||
|
||||
receiverSys.ResolveApc(Owner, ref receiver);
|
||||
|
||||
// Also set in frameupdates.
|
||||
if (receiver != null)
|
||||
{
|
||||
_window.SetActive(!receiver.PowerDisabled);
|
||||
}
|
||||
|
||||
_window.SetTemperature(cast.Temperature);
|
||||
_window.SetActive(cast.Enabled);
|
||||
_window.Title = _isHeater switch
|
||||
{
|
||||
false => Loc.GetString("comp-gas-thermomachine-ui-title-freezer"),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
MinSize="300 120" Title="{Loc comp-gas-thermomachine-ui-title-freezer}">
|
||||
<BoxContainer Name="VboxContainer" Orientation="Vertical" Margin="5 5 5 5" SeparationOverride="10">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
|
|
@ -11,4 +12,4 @@
|
|||
<Label Text="{Loc comp-gas-thermomachine-ui-temperature}"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
</controls:FancyWindow>
|
||||
|
|
|
|||
|
|
@ -1,19 +1,26 @@
|
|||
using Content.Client.Power.Components;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Atmos.UI;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class GasThermomachineWindow : DefaultWindow
|
||||
public sealed partial class GasThermomachineWindow : FancyWindow
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
|
||||
public bool Active = true;
|
||||
|
||||
public FloatSpinBox TemperatureSpinbox;
|
||||
|
||||
public EntityUid Entity;
|
||||
|
||||
public GasThermomachineWindow()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
SpinboxHBox.AddChild(
|
||||
|
|
@ -27,12 +34,10 @@ public sealed partial class GasThermomachineWindow : DefaultWindow
|
|||
if (active)
|
||||
{
|
||||
ToggleStatusButton.Text = Loc.GetString("comp-gas-thermomachine-ui-status-enabled");
|
||||
ToggleStatusButton.Pressed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ToggleStatusButton.Text = Loc.GetString("comp-gas-thermomachine-ui-status-disabled");
|
||||
ToggleStatusButton.Pressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -40,4 +45,14 @@ public sealed partial class GasThermomachineWindow : DefaultWindow
|
|||
{
|
||||
TemperatureSpinbox.Value = temperature;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
|
||||
if (_entManager.TryGetComponent(Entity, out ApcPowerReceiverComponent? receiver))
|
||||
{
|
||||
SetActive(!receiver.PowerDisabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ using Robust.Client.GameObjects;
|
|||
using Content.Shared.Atmos.Visuals;
|
||||
using Content.Client.Power;
|
||||
|
||||
namespace Content.Client.Atmos.Visualizers
|
||||
namespace Content.Client.Atmos.Visualizers;
|
||||
|
||||
/// <summary>
|
||||
/// Controls client-side visuals for portable scrubbers.
|
||||
/// </summary>
|
||||
public sealed class PortableScrubberSystem : VisualizerSystem<PortableScrubberVisualsComponent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls client-side visuals for portable scrubbers.
|
||||
/// </summary>
|
||||
public sealed class PortableScrubberSystem : VisualizerSystem<PortableScrubberVisualsComponent>
|
||||
{
|
||||
protected override void OnAppearanceChange(EntityUid uid, PortableScrubberVisualsComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null)
|
||||
|
|
@ -18,19 +18,19 @@ namespace Content.Client.Atmos.Visualizers
|
|||
&& AppearanceSystem.TryGetData<bool>(uid, PortableScrubberVisuals.IsRunning, out var isRunning, args.Component))
|
||||
{
|
||||
var runningState = isRunning ? component.RunningState : component.IdleState;
|
||||
args.Sprite.LayerSetState(PortableScrubberVisualLayers.IsRunning, runningState);
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), PortableScrubberVisualLayers.IsRunning, runningState);
|
||||
|
||||
var fullState = isFull ? component.FullState : component.ReadyState;
|
||||
args.Sprite.LayerSetState(PowerDeviceVisualLayers.Powered, fullState);
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), PowerDeviceVisualLayers.Powered, fullState);
|
||||
}
|
||||
|
||||
if (AppearanceSystem.TryGetData<bool>(uid, PortableScrubberVisuals.IsDraining, out var isDraining, args.Component))
|
||||
{
|
||||
args.Sprite.LayerSetVisible(PortableScrubberVisualLayers.IsDraining, isDraining);
|
||||
}
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), PortableScrubberVisualLayers.IsDraining, isDraining);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum PortableScrubberVisualLayers : byte
|
||||
{
|
||||
IsRunning,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ public sealed class JukeboxSystem : SharedJukeboxSystem
|
|||
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -64,7 +65,7 @@ public sealed class JukeboxSystem : SharedJukeboxSystem
|
|||
visualState = JukeboxVisualState.On;
|
||||
}
|
||||
|
||||
UpdateAppearance(uid, visualState, component, sprite);
|
||||
UpdateAppearance((uid, sprite), visualState, component);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(EntityUid uid, JukeboxComponent component, ref AppearanceChangeEvent args)
|
||||
|
|
@ -78,25 +79,25 @@ public sealed class JukeboxSystem : SharedJukeboxSystem
|
|||
visualState = JukeboxVisualState.On;
|
||||
}
|
||||
|
||||
UpdateAppearance(uid, visualState, component, args.Sprite);
|
||||
UpdateAppearance((uid, args.Sprite), visualState, component);
|
||||
}
|
||||
|
||||
private void UpdateAppearance(EntityUid uid, JukeboxVisualState visualState, JukeboxComponent component, SpriteComponent sprite)
|
||||
private void UpdateAppearance(Entity<SpriteComponent> entity, JukeboxVisualState visualState, JukeboxComponent component)
|
||||
{
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OffState, sprite);
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OffState, entity);
|
||||
|
||||
switch (visualState)
|
||||
{
|
||||
case JukeboxVisualState.On:
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OnState, sprite);
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OnState, entity);
|
||||
break;
|
||||
|
||||
case JukeboxVisualState.Off:
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OffState, sprite);
|
||||
SetLayerState(JukeboxVisualLayers.Base, component.OffState, entity);
|
||||
break;
|
||||
|
||||
case JukeboxVisualState.Select:
|
||||
PlayAnimation(uid, JukeboxVisualLayers.Base, component.SelectState, 1.0f, sprite);
|
||||
PlayAnimation(entity.Owner, JukeboxVisualLayers.Base, component.SelectState, 1.0f, entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +110,7 @@ public sealed class JukeboxSystem : SharedJukeboxSystem
|
|||
if (!_animationPlayer.HasRunningAnimation(uid, state))
|
||||
{
|
||||
var animation = GetAnimation(layer, state, animationTime);
|
||||
sprite.LayerSetVisible(layer, true);
|
||||
_sprite.LayerSetVisible((uid, sprite), layer, true);
|
||||
_animationPlayer.Play(uid, animation, state);
|
||||
}
|
||||
}
|
||||
|
|
@ -133,13 +134,13 @@ public sealed class JukeboxSystem : SharedJukeboxSystem
|
|||
};
|
||||
}
|
||||
|
||||
private void SetLayerState(JukeboxVisualLayers layer, string? state, SpriteComponent sprite)
|
||||
private void SetLayerState(JukeboxVisualLayers layer, string? state, Entity<SpriteComponent> sprite)
|
||||
{
|
||||
if (string.IsNullOrEmpty(state))
|
||||
return;
|
||||
|
||||
sprite.LayerSetVisible(layer, true);
|
||||
sprite.LayerSetAutoAnimated(layer, true);
|
||||
sprite.LayerSetState(layer, state);
|
||||
_sprite.LayerSetVisible(sprite.AsNullable(), layer, true);
|
||||
_sprite.LayerSetAutoAnimated(sprite.AsNullable(), layer, true);
|
||||
_sprite.LayerSetRsiState(sprite.AsNullable(), layer, state);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,12 +41,12 @@ public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
|
|||
&& sign.Current != null
|
||||
&& _prototypeManager.TryIndex(sign.Current, out var proto))
|
||||
{
|
||||
sprite.LayerSetSprite(0, proto.Icon);
|
||||
SpriteSystem.LayerSetSprite((id, sprite), 0, proto.Icon);
|
||||
sprite.LayerSetShader(0, "unshaded");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(0, "empty");
|
||||
SpriteSystem.LayerSetRsiState((id, sprite), 0, "empty");
|
||||
sprite.LayerSetShader(0, null, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ namespace Content.Client.Beam;
|
|||
|
||||
public sealed class BeamSystem : SharedBeamSystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
|
@ -21,11 +23,11 @@ public sealed class BeamSystem : SharedBeamSystem
|
|||
|
||||
if (TryComp<SpriteComponent>(beam, out var sprites))
|
||||
{
|
||||
sprites.Rotation = args.UserAngle;
|
||||
_sprite.SetRotation((beam, sprites), args.UserAngle);
|
||||
|
||||
if (args.BodyState != null)
|
||||
{
|
||||
sprites.LayerSetState(0, args.BodyState);
|
||||
_sprite.LayerSetRsiState((beam, sprites), 0, args.BodyState);
|
||||
sprites.LayerSetShader(0, args.Shader);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
8
Content.Client/Bed/BedSystem.cs
Normal file
8
Content.Client/Bed/BedSystem.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
using Content.Shared.Bed;
|
||||
|
||||
namespace Content.Client.Bed;
|
||||
|
||||
public sealed class BedSystem : SharedBedSystem
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ public sealed class StasisBedSystem : VisualizerSystem<StasisBedVisualsComponent
|
|||
if (args.Sprite != null
|
||||
&& AppearanceSystem.TryGetData<bool>(uid, StasisBedVisuals.IsOn, out var isOn, args.Component))
|
||||
{
|
||||
args.Sprite.LayerSetVisible(StasisBedVisualLayers.IsOn, isOn);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), StasisBedVisualLayers.IsOn, isOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Content.Client.Botany.Components;
|
||||
using Content.Shared.Botany;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Botany;
|
||||
|
||||
|
|
@ -17,8 +18,8 @@ public sealed class PlantHolderVisualizerSystem : VisualizerSystem<PlantHolderVi
|
|||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
sprite.LayerMapReserveBlank(PlantHolderLayers.Plant);
|
||||
sprite.LayerSetVisible(PlantHolderLayers.Plant, false);
|
||||
SpriteSystem.LayerMapReserve((uid, sprite), PlantHolderLayers.Plant);
|
||||
SpriteSystem.LayerSetVisible((uid, sprite), PlantHolderLayers.Plant, false);
|
||||
}
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, PlantHolderVisualsComponent component, ref AppearanceChangeEvent args)
|
||||
|
|
@ -31,12 +32,12 @@ public sealed class PlantHolderVisualizerSystem : VisualizerSystem<PlantHolderVi
|
|||
{
|
||||
var valid = !string.IsNullOrWhiteSpace(state);
|
||||
|
||||
args.Sprite.LayerSetVisible(PlantHolderLayers.Plant, valid);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), PlantHolderLayers.Plant, valid);
|
||||
|
||||
if (valid)
|
||||
{
|
||||
args.Sprite.LayerSetRSI(PlantHolderLayers.Plant, rsi);
|
||||
args.Sprite.LayerSetState(PlantHolderLayers.Plant, state);
|
||||
SpriteSystem.LayerSetRsi((uid, args.Sprite), PlantHolderLayers.Plant, new ResPath(rsi));
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), PlantHolderLayers.Plant, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public sealed class PotencyVisualsSystem : VisualizerSystem<PotencyVisualsCompon
|
|||
if (AppearanceSystem.TryGetData<float>(uid, ProduceVisuals.Potency, out var potency, args.Component))
|
||||
{
|
||||
var scale = MathHelper.Lerp(component.MinimumScale, component.MaximumScale, potency / 100);
|
||||
args.Sprite.Scale = new Vector2(scale, scale);
|
||||
SpriteSystem.SetScale((uid, args.Sprite), new Vector2(scale, scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ internal sealed class BuckleSystem : SharedBuckleSystem
|
|||
[Dependency] private readonly RotationVisualizerSystem _rotationVisualizerSystem = default!;
|
||||
[Dependency] private readonly IEyeManager _eye = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _xformSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -69,11 +70,11 @@ internal sealed class BuckleSystem : SharedBuckleSystem
|
|||
{
|
||||
// This will only assign if empty, it won't get overwritten by new depth on multiple calls, which do happen easily
|
||||
buckle.OriginalDrawDepth ??= buckledSprite.DrawDepth;
|
||||
buckledSprite.DrawDepth = strapSprite.DrawDepth - 1;
|
||||
_sprite.SetDrawDepth((buckledEntity, buckledSprite), strapSprite.DrawDepth - 1);
|
||||
}
|
||||
else if (buckle.OriginalDrawDepth.HasValue)
|
||||
{
|
||||
buckledSprite.DrawDepth = buckle.OriginalDrawDepth.Value;
|
||||
_sprite.SetDrawDepth((buckledEntity, buckledSprite), buckle.OriginalDrawDepth.Value);
|
||||
buckle.OriginalDrawDepth = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -97,7 +98,7 @@ internal sealed class BuckleSystem : SharedBuckleSystem
|
|||
return;
|
||||
|
||||
ent.Comp.OriginalDrawDepth ??= buckledSprite.DrawDepth;
|
||||
buckledSprite.DrawDepth = strapSprite.DrawDepth - 1;
|
||||
_sprite.SetDrawDepth((ent.Owner, buckledSprite), strapSprite.DrawDepth - 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -111,7 +112,7 @@ internal sealed class BuckleSystem : SharedBuckleSystem
|
|||
if (!ent.Comp.OriginalDrawDepth.HasValue)
|
||||
return;
|
||||
|
||||
buckledSprite.DrawDepth = ent.Comp.OriginalDrawDepth.Value;
|
||||
_sprite.SetDrawDepth((ent.Owner, buckledSprite), ent.Comp.OriginalDrawDepth.Value);
|
||||
ent.Comp.OriginalDrawDepth = null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
|
|||
[Dependency] private readonly EntityLookupSystem _entityLookup = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private EntityQuery<BodyComponent> _bodyQuery;
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
|
|||
if (!xformQuery.TryGetComponent(ent, out var entTransform) || !TryComp<SpriteComponent>(ent, out var sprite))
|
||||
continue;
|
||||
|
||||
sprite.Offset = new Vector2(0, 1);
|
||||
_sprite.SetOffset((ent, sprite), new Vector2(0, 1));
|
||||
_transform.SetParent(ent, entTransform, mob);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,11 @@ namespace Content.Client.Cargo.BUI
|
|||
|
||||
AccountName = cState.Name;
|
||||
|
||||
if (_menu == null)
|
||||
return;
|
||||
|
||||
_menu.ProductCatalogue = cState.Products;
|
||||
|
||||
_menu?.UpdateStation(station);
|
||||
Populate(cState.Orders);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace Content.Client.Cargo.Systems;
|
|||
public sealed partial class CargoSystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private static readonly Animation CargoTelepadBeamAnimation = new()
|
||||
{
|
||||
|
|
@ -80,12 +81,12 @@ public sealed partial class CargoSystem
|
|||
_player.Play((uid, player), CargoTelepadBeamAnimation, TelepadBeamKey);
|
||||
break;
|
||||
case CargoTelepadState.Unpowered:
|
||||
sprite.LayerSetVisible(CargoTelepadLayers.Beam, false);
|
||||
_sprite.LayerSetVisible((uid, sprite), CargoTelepadLayers.Beam, false);
|
||||
_player.Stop(uid, player, TelepadBeamKey);
|
||||
_player.Stop(uid, player, TelepadIdleKey);
|
||||
break;
|
||||
default:
|
||||
sprite.LayerSetVisible(CargoTelepadLayers.Beam, true);
|
||||
_sprite.LayerSetVisible((uid, sprite), CargoTelepadLayers.Beam, true);
|
||||
|
||||
if (_player.HasRunningAnimation(uid, player, TelepadIdleKey) ||
|
||||
_player.HasRunningAnimation(uid, player, TelepadBeamKey))
|
||||
|
|
|
|||
|
|
@ -38,9 +38,10 @@
|
|||
<!-- Products get added here by code -->
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
<Control MinHeight="5"/>
|
||||
<Control MinHeight="5" Name="OrdersSpacer"/>
|
||||
<PanelContainer VerticalExpand="True"
|
||||
SizeFlagsStretchRatio="1">
|
||||
SizeFlagsStretchRatio="1"
|
||||
Name="Orders">
|
||||
<PanelContainer.PanelOverride>
|
||||
<gfx:StyleBoxFlat BackgroundColor="#000000" />
|
||||
</PanelContainer.PanelOverride>
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ namespace Content.Client.Cargo.UI
|
|||
private readonly List<string> _categoryStrings = new();
|
||||
private string? _category;
|
||||
|
||||
public List<ProtoId<CargoProductPrototype>> ProductCatalogue = new();
|
||||
|
||||
public CargoConsoleMenu(EntityUid owner, IEntityManager entMan, IPrototypeManager protoManager, SpriteSystem spriteSystem)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
|
@ -113,14 +115,16 @@ namespace Content.Client.Cargo.UI
|
|||
Categories.SelectId(id);
|
||||
}
|
||||
|
||||
public IEnumerable<CargoProductPrototype> ProductPrototypes
|
||||
private IEnumerable<CargoProductPrototype> ProductPrototypes
|
||||
{
|
||||
get
|
||||
{
|
||||
var allowedGroups = _entityManager.GetComponentOrNull<CargoOrderConsoleComponent>(_owner)?.AllowedGroups;
|
||||
|
||||
foreach (var cargoPrototype in _protoManager.EnumeratePrototypes<CargoProductPrototype>())
|
||||
foreach (var cargoPrototypeId in ProductCatalogue)
|
||||
{
|
||||
var cargoPrototype = _protoManager.Index(cargoPrototypeId);
|
||||
|
||||
if (!allowedGroups?.Contains(cargoPrototype.Group) ?? false)
|
||||
continue;
|
||||
|
||||
|
|
@ -208,6 +212,7 @@ namespace Content.Client.Cargo.UI
|
|||
|
||||
var product = _protoManager.Index<EntityPrototype>(order.ProductId);
|
||||
var productName = product.Name;
|
||||
var account = _protoManager.Index(order.Account);
|
||||
|
||||
var row = new CargoOrderRow
|
||||
{
|
||||
|
|
@ -219,7 +224,9 @@ namespace Content.Client.Cargo.UI
|
|||
"cargo-console-menu-populate-orders-cargo-order-row-product-name-text",
|
||||
("productName", productName),
|
||||
("orderAmount", order.OrderQuantity),
|
||||
("orderRequester", order.Requester))
|
||||
("orderRequester", order.Requester),
|
||||
("accountColor", account.Color),
|
||||
("account", Loc.GetString(account.Code)))
|
||||
},
|
||||
Description =
|
||||
{
|
||||
|
|
@ -282,6 +289,9 @@ namespace Content.Client.Cargo.UI
|
|||
AccountActionButton.Disabled = TransferSpinBox.Value <= 0 ||
|
||||
TransferSpinBox.Value > bankAccount.Accounts[orderConsole.Account] * orderConsole.TransferLimit ||
|
||||
_timing.CurTime < orderConsole.NextAccountActionTime;
|
||||
|
||||
OrdersSpacer.Visible = !orderConsole.SlipPrinter;
|
||||
Orders.Visible = !orderConsole.SlipPrinter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,10 @@
|
|||
<BoxContainer Orientation="Vertical"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True">
|
||||
<Label Name="ProductName"
|
||||
<RichTextLabel Name="ProductName"
|
||||
Access="Public"
|
||||
HorizontalExpand="True"
|
||||
StyleClasses="LabelSubText"
|
||||
ClipText="True" />
|
||||
StyleClasses="LabelSubText" />
|
||||
<Label Name="Description"
|
||||
Access="Public"
|
||||
HorizontalExpand="True"
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ namespace Content.Client.Cargo.UI
|
|||
{
|
||||
var product = protoManager.Index<EntityPrototype>(order.ProductId);
|
||||
var productName = product.Name;
|
||||
var account = protoManager.Index(order.Account);
|
||||
|
||||
var row = new CargoOrderRow
|
||||
{
|
||||
|
|
@ -47,7 +48,9 @@ namespace Content.Client.Cargo.UI
|
|||
"cargo-console-menu-populate-orders-cargo-order-row-product-name-text",
|
||||
("productName", productName),
|
||||
("orderAmount", order.OrderQuantity - order.NumDispatched),
|
||||
("orderRequester", order.Requester))
|
||||
("orderRequester", order.Requester),
|
||||
("accountColor", account.Color),
|
||||
("account", Loc.GetString(account.Code)))
|
||||
},
|
||||
Description = {Text = Loc.GetString("cargo-console-menu-order-reason-description",
|
||||
("reason", order.Reason))}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace Content.Client.Chasm;
|
|||
public sealed class ChasmFallingVisualsSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _anim = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private readonly string _chasmFallAnimationKey = "chasm_fall";
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ public sealed class ChasmFallingVisualsSystem : EntitySystem
|
|||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
|
||||
sprite.Scale = component.OriginalScale;
|
||||
_sprite.SetScale((uid, sprite), component.OriginalScale);
|
||||
|
||||
if (!TryComp<AnimationPlayerComponent>(uid, out var player))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public sealed class TypingIndicatorSystem : SharedTypingIndicatorSystem
|
|||
private readonly TimeSpan _typingTimeout = TimeSpan.FromSeconds(2);
|
||||
private TimeSpan _lastTextChange;
|
||||
private bool _isClientTyping;
|
||||
private bool _isClientChatFocused;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -31,7 +32,8 @@ public sealed class TypingIndicatorSystem : SharedTypingIndicatorSystem
|
|||
return;
|
||||
|
||||
// client typed something - show typing indicator
|
||||
ClientUpdateTyping(true);
|
||||
_isClientTyping = true;
|
||||
ClientUpdateTyping();
|
||||
_lastTextChange = _time.CurTime;
|
||||
}
|
||||
|
||||
|
|
@ -42,36 +44,53 @@ public sealed class TypingIndicatorSystem : SharedTypingIndicatorSystem
|
|||
return;
|
||||
|
||||
// client submitted text - hide typing indicator
|
||||
ClientUpdateTyping(false);
|
||||
_isClientTyping = false;
|
||||
ClientUpdateTyping();
|
||||
}
|
||||
|
||||
public void ClientChangedChatFocus(bool isFocused)
|
||||
{
|
||||
// don't update it if player don't want to show typing
|
||||
if (!_cfg.GetCVar(CCVars.ChatShowTypingIndicator))
|
||||
return;
|
||||
|
||||
// client submitted text - hide typing indicator
|
||||
_isClientChatFocused = isFocused;
|
||||
ClientUpdateTyping();
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
if (!_time.IsFirstTimePredicted)
|
||||
return;
|
||||
|
||||
// check if client didn't changed chat text box for a long time
|
||||
if (_isClientTyping)
|
||||
{
|
||||
var dif = _time.CurTime - _lastTextChange;
|
||||
if (dif > _typingTimeout)
|
||||
{
|
||||
// client didn't typed anything for a long time - hide indicator
|
||||
ClientUpdateTyping(false);
|
||||
// client didn't typed anything for a long time - change indicator
|
||||
_isClientTyping = false;
|
||||
ClientUpdateTyping();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClientUpdateTyping(bool isClientTyping)
|
||||
private void ClientUpdateTyping()
|
||||
{
|
||||
if (_isClientTyping == isClientTyping)
|
||||
return;
|
||||
|
||||
// check if player controls any entity.
|
||||
// check if player controls any pawn
|
||||
if (_playerManager.LocalEntity == null)
|
||||
return;
|
||||
|
||||
_isClientTyping = isClientTyping;
|
||||
RaisePredictiveEvent(new TypingChangedEvent(isClientTyping));
|
||||
var state = TypingIndicatorState.None;
|
||||
if (_isClientChatFocused)
|
||||
state = _isClientTyping ? TypingIndicatorState.Typing : TypingIndicatorState.Idle;
|
||||
|
||||
// send a networked event to server
|
||||
RaisePredictiveEvent(new TypingChangedEvent(state));
|
||||
}
|
||||
|
||||
private void OnShowTypingChanged(bool showTyping)
|
||||
|
|
@ -79,7 +98,8 @@ public sealed class TypingIndicatorSystem : SharedTypingIndicatorSystem
|
|||
// hide typing indicator immediately if player don't want to show it anymore
|
||||
if (!showTyping)
|
||||
{
|
||||
ClientUpdateTyping(false);
|
||||
_isClientTyping = false;
|
||||
ClientUpdateTyping();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using Content.Shared.Chat.TypingIndicator;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared.Inventory;
|
||||
|
||||
|
|
@ -11,7 +10,6 @@ public sealed class TypingIndicatorVisualizerSystem : VisualizerSystem<TypingInd
|
|||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, TypingIndicatorComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null)
|
||||
|
|
@ -35,15 +33,25 @@ public sealed class TypingIndicatorVisualizerSystem : VisualizerSystem<TypingInd
|
|||
return;
|
||||
}
|
||||
|
||||
AppearanceSystem.TryGetData<bool>(uid, TypingIndicatorVisuals.IsTyping, out var isTyping, args.Component);
|
||||
var layerExists = args.Sprite.LayerMapTryGet(TypingIndicatorLayers.Base, out var layer);
|
||||
var layerExists = SpriteSystem.LayerMapTryGet((uid, args.Sprite), TypingIndicatorLayers.Base, out var layer, false);
|
||||
if (!layerExists)
|
||||
layer = args.Sprite.LayerMapReserveBlank(TypingIndicatorLayers.Base);
|
||||
layer = SpriteSystem.LayerMapReserve((uid, args.Sprite), TypingIndicatorLayers.Base);
|
||||
|
||||
args.Sprite.LayerSetRSI(layer, proto.SpritePath);
|
||||
args.Sprite.LayerSetState(layer, proto.TypingState);
|
||||
SpriteSystem.LayerSetRsi((uid, args.Sprite), layer, proto.SpritePath);
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), layer, proto.TypingState);
|
||||
args.Sprite.LayerSetShader(layer, proto.Shader);
|
||||
args.Sprite.LayerSetOffset(layer, proto.Offset);
|
||||
args.Sprite.LayerSetVisible(layer, isTyping);
|
||||
SpriteSystem.LayerSetOffset((uid, args.Sprite), layer, proto.Offset);
|
||||
|
||||
AppearanceSystem.TryGetData<TypingIndicatorState>(uid, TypingIndicatorVisuals.State, out var state);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), layer, state != TypingIndicatorState.None);
|
||||
switch (state)
|
||||
{
|
||||
case TypingIndicatorState.Idle:
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), layer, proto.IdleState);
|
||||
break;
|
||||
case TypingIndicatorState.Typing:
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), layer, proto.TypingState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ namespace Content.Client.Chemistry.EntitySystems;
|
|||
|
||||
public sealed class PillSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
|
@ -16,9 +18,9 @@ public sealed class PillSystem : EntitySystem
|
|||
if (!TryComp(uid, out SpriteComponent? sprite))
|
||||
return;
|
||||
|
||||
if (!sprite.TryGetLayer(0, out var layer))
|
||||
if (!_sprite.TryGetLayer((uid, sprite), 0, out var layer, false))
|
||||
return;
|
||||
|
||||
layer.SetState($"pill{component.PillType + 1}");
|
||||
_sprite.LayerSetRsiState(layer, $"pill{component.PillType + 1}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public sealed class HyposprayStatusControl : Control
|
|||
PrevMaxVolume = solution.MaxVolume;
|
||||
PrevOnlyAffectsMobs = _parent.Comp.OnlyAffectsMobs;
|
||||
|
||||
var modeStringLocalized = Loc.GetString(_parent.Comp.OnlyAffectsMobs switch
|
||||
var modeStringLocalized = Loc.GetString((_parent.Comp.OnlyAffectsMobs && _parent.Comp.CanContainerDraw) switch
|
||||
{
|
||||
false => "hypospray-all-mode-text",
|
||||
true => "hypospray-mobs-only-mode-text",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
|
|
@ -9,15 +10,15 @@ namespace Content.Client.Chemistry.UI;
|
|||
[GenerateTypedNameReferences]
|
||||
public sealed partial class ReagentCardControl : Control
|
||||
{
|
||||
public string StorageSlotId { get; }
|
||||
public Action<string>? OnPressed;
|
||||
public Action<string>? OnEjectButtonPressed;
|
||||
public ItemStorageLocation StorageLocation { get; }
|
||||
public Action<ItemStorageLocation>? OnPressed;
|
||||
public Action<ItemStorageLocation>? OnEjectButtonPressed;
|
||||
|
||||
public ReagentCardControl(ReagentInventoryItem item)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
StorageSlotId = item.StorageSlotId;
|
||||
StorageLocation = item.StorageLocation;
|
||||
ColorPanel.PanelOverride = new StyleBoxFlat { BackgroundColor = item.ReagentColor };
|
||||
ReagentNameLabel.Text = item.ReagentLabel;
|
||||
FillLabel.Text = Loc.GetString("reagent-dispenser-window-quantity-label-text", ("quantity", item.Quantity));;
|
||||
|
|
@ -26,7 +27,7 @@ public sealed partial class ReagentCardControl : Control
|
|||
if (item.Quantity == 0.0)
|
||||
MainButton.Disabled = true;
|
||||
|
||||
MainButton.OnPressed += args => OnPressed?.Invoke(StorageSlotId);
|
||||
EjectButton.OnPressed += args => OnEjectButtonPressed?.Invoke(StorageSlotId);
|
||||
MainButton.OnPressed += args => OnPressed?.Invoke(StorageLocation);
|
||||
EjectButton.OnPressed += args => OnEjectButtonPressed?.Invoke(StorageLocation);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ namespace Content.Client.Chemistry.UI
|
|||
|
||||
_window.AmountGrid.OnButtonPressed += s => SendMessage(new ReagentDispenserSetDispenseAmountMessage(s));
|
||||
|
||||
_window.OnDispenseReagentButtonPressed += (id) => SendMessage(new ReagentDispenserDispenseReagentMessage(id));
|
||||
_window.OnEjectJugButtonPressed += (id) => SendMessage(new ItemSlotButtonPressedEvent(id));
|
||||
_window.OnDispenseReagentButtonPressed += (location) => SendMessage(new ReagentDispenserDispenseReagentMessage(location));
|
||||
_window.OnEjectJugButtonPressed += (location) => SendMessage(new ReagentDispenserEjectContainerMessage(location));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using Content.Client.Stylesheets;
|
|||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
|
@ -18,8 +19,8 @@ namespace Content.Client.Chemistry.UI
|
|||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
public event Action<string>? OnDispenseReagentButtonPressed;
|
||||
public event Action<string>? OnEjectJugButtonPressed;
|
||||
public event Action<ItemStorageLocation>? OnDispenseReagentButtonPressed;
|
||||
public event Action<ItemStorageLocation>? OnEjectJugButtonPressed;
|
||||
|
||||
/// <summary>
|
||||
/// Create and initialize the dispenser UI client-side. Creates the basic layout,
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public sealed class FoamVisualizerSystem : VisualizerSystem<FoamVisualsComponent
|
|||
return;
|
||||
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite))
|
||||
sprite.Visible = false;
|
||||
SpriteSystem.SetVisible((uid, sprite), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ public sealed class SmokeVisualizerSystem : VisualizerSystem<SmokeVisualsCompone
|
|||
{
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
if(!AppearanceSystem.TryGetData<Color>(uid, SmokeVisuals.Color, out var color))
|
||||
if (!AppearanceSystem.TryGetData<Color>(uid, SmokeVisuals.Color, out var color))
|
||||
return;
|
||||
args.Sprite.Color = color;
|
||||
SpriteSystem.SetColor((uid, args.Sprite), color);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public sealed class SolutionContainerVisualsSystem : VisualizerSystem<SolutionCo
|
|||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
if (!args.Sprite.LayerMapTryGet(component.Layer, out var fillLayer))
|
||||
if (!SpriteSystem.LayerMapTryGet((uid, args.Sprite), component.Layer, out var fillLayer, false))
|
||||
return;
|
||||
|
||||
var maxFillLevels = component.MaxFillLevels;
|
||||
|
|
@ -67,9 +67,9 @@ public sealed class SolutionContainerVisualsSystem : VisualizerSystem<SolutionCo
|
|||
}
|
||||
if (component.Metamorphic)
|
||||
{
|
||||
if (args.Sprite.LayerMapTryGet(component.BaseLayer, out var baseLayer))
|
||||
if (SpriteSystem.LayerMapTryGet((uid, args.Sprite), component.BaseLayer, out var baseLayer, false))
|
||||
{
|
||||
var hasOverlay = args.Sprite.LayerMapTryGet(component.OverlayLayer, out var overlayLayer);
|
||||
var hasOverlay = SpriteSystem.LayerMapTryGet((uid, args.Sprite), component.OverlayLayer, out var overlayLayer, false);
|
||||
|
||||
if (AppearanceSystem.TryGetData<string>(uid, SolutionContainerVisuals.BaseOverride,
|
||||
out var baseOverride,
|
||||
|
|
@ -79,35 +79,35 @@ public sealed class SolutionContainerVisualsSystem : VisualizerSystem<SolutionCo
|
|||
|
||||
if (reagentProto?.MetamorphicSprite is { } sprite)
|
||||
{
|
||||
args.Sprite.LayerSetSprite(baseLayer, sprite);
|
||||
SpriteSystem.LayerSetSprite((uid, args.Sprite), baseLayer, sprite);
|
||||
if (reagentProto.MetamorphicMaxFillLevels > 0)
|
||||
{
|
||||
args.Sprite.LayerSetVisible(fillLayer, true);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), fillLayer, true);
|
||||
maxFillLevels = reagentProto.MetamorphicMaxFillLevels;
|
||||
fillBaseName = reagentProto.MetamorphicFillBaseName;
|
||||
changeColor = reagentProto.MetamorphicChangeColor;
|
||||
fillSprite = sprite;
|
||||
}
|
||||
else
|
||||
args.Sprite.LayerSetVisible(fillLayer, false);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), fillLayer, false);
|
||||
|
||||
if (hasOverlay)
|
||||
args.Sprite.LayerSetVisible(overlayLayer, false);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), overlayLayer, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Sprite.LayerSetVisible(fillLayer, true);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), fillLayer, true);
|
||||
if (hasOverlay)
|
||||
args.Sprite.LayerSetVisible(overlayLayer, true);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), overlayLayer, true);
|
||||
if (component.MetamorphicDefaultSprite != null)
|
||||
args.Sprite.LayerSetSprite(baseLayer, component.MetamorphicDefaultSprite);
|
||||
SpriteSystem.LayerSetSprite((uid, args.Sprite), baseLayer, component.MetamorphicDefaultSprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Sprite.LayerSetVisible(fillLayer, true);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), fillLayer, true);
|
||||
}
|
||||
|
||||
var closestFillSprite = ContentHelpers.RoundToLevels(fraction, 1, maxFillLevels + 1);
|
||||
|
|
@ -119,25 +119,25 @@ public sealed class SolutionContainerVisualsSystem : VisualizerSystem<SolutionCo
|
|||
|
||||
var stateName = fillBaseName + closestFillSprite;
|
||||
if (fillSprite != null)
|
||||
args.Sprite.LayerSetSprite(fillLayer, fillSprite);
|
||||
args.Sprite.LayerSetState(fillLayer, stateName);
|
||||
SpriteSystem.LayerSetSprite((uid, args.Sprite), fillLayer, fillSprite);
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), fillLayer, stateName);
|
||||
|
||||
if (changeColor && AppearanceSystem.TryGetData<Color>(uid, SolutionContainerVisuals.Color, out var color, args.Component))
|
||||
args.Sprite.LayerSetColor(fillLayer, color);
|
||||
SpriteSystem.LayerSetColor((uid, args.Sprite), fillLayer, color);
|
||||
else
|
||||
args.Sprite.LayerSetColor(fillLayer, Color.White);
|
||||
SpriteSystem.LayerSetColor((uid, args.Sprite), fillLayer, Color.White);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (component.EmptySpriteName == null)
|
||||
args.Sprite.LayerSetVisible(fillLayer, false);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), fillLayer, false);
|
||||
else
|
||||
{
|
||||
args.Sprite.LayerSetState(fillLayer, component.EmptySpriteName);
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), fillLayer, component.EmptySpriteName);
|
||||
if (changeColor)
|
||||
args.Sprite.LayerSetColor(fillLayer, component.EmptySpriteColor);
|
||||
SpriteSystem.LayerSetColor((uid, args.Sprite), fillLayer, component.EmptySpriteColor);
|
||||
else
|
||||
args.Sprite.LayerSetColor(fillLayer, Color.White);
|
||||
SpriteSystem.LayerSetColor((uid, args.Sprite), fillLayer, Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public sealed class VaporVisualizerSystem : VisualizerSystem<VaporVisualsCompone
|
|||
{
|
||||
if (AppearanceSystem.TryGetData<Color>(uid, VaporVisuals.Color, out var color, args.Component) && args.Sprite != null)
|
||||
{
|
||||
args.Sprite.Color = color;
|
||||
SpriteSystem.SetColor((uid, args.Sprite), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,10 +77,10 @@ public sealed class ClickableSystem : EntitySystem
|
|||
drawDepth = sprite.DrawDepth;
|
||||
renderOrder = sprite.RenderOrder;
|
||||
var (spritePos, spriteRot) = _transforms.GetWorldPositionRotation(transform);
|
||||
var spriteBB = sprite.CalculateRotatedBoundingBox(spritePos, spriteRot, eye.Rotation);
|
||||
var spriteBB = _sprites.CalculateBounds((entity.Owner, sprite), spritePos, spriteRot, eye.Rotation);
|
||||
bottom = Matrix3Helpers.CreateRotation(eye.Rotation).TransformBox(spriteBB).Bottom;
|
||||
|
||||
Matrix3x2.Invert(sprite.GetLocalMatrix(), out var invSpriteMatrix);
|
||||
Matrix3x2.Invert(sprite.LocalMatrix, out var invSpriteMatrix);
|
||||
|
||||
// This should have been the rotation of the sprite relative to the screen, but this is not the case with no-rot or directional sprites.
|
||||
var relativeRotation = (spriteRot + eye.Rotation).Reduced().FlipPositive();
|
||||
|
|
@ -107,7 +107,7 @@ public sealed class ClickableSystem : EntitySystem
|
|||
if (layer.Texture != null)
|
||||
{
|
||||
// Convert to image coordinates
|
||||
var imagePos = (Vector2i) (localPos * EyeManager.PixelsPerMeter * new Vector2(1, -1) + layer.Texture.Size / 2f);
|
||||
var imagePos = (Vector2i)(localPos * EyeManager.PixelsPerMeter * new Vector2(1, -1) + layer.Texture.Size / 2f);
|
||||
|
||||
if (_clickMapManager.IsOccluding(layer.Texture, imagePos))
|
||||
return true;
|
||||
|
|
@ -125,7 +125,7 @@ public sealed class ClickableSystem : EntitySystem
|
|||
var layerLocal = Vector2.Transform(localPos, inverseMatrix);
|
||||
|
||||
// Convert to image coordinates
|
||||
var layerImagePos = (Vector2i) (layerLocal * EyeManager.PixelsPerMeter * new Vector2(1, -1) + rsiState.Size / 2f);
|
||||
var layerImagePos = (Vector2i)(layerLocal * EyeManager.PixelsPerMeter * new Vector2(1, -1) + rsiState.Size / 2f);
|
||||
|
||||
// Next, to get the right click map we need the "direction" of this layer that is actually being used to draw the sprite on the screen.
|
||||
// This **can** differ from the dir defined before, but can also just be the same.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ namespace Content.Client.Clock;
|
|||
|
||||
public sealed class ClockSystem : SharedClockSystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
|
@ -12,15 +14,15 @@ public sealed class ClockSystem : SharedClockSystem
|
|||
var query = EntityQueryEnumerator<ClockComponent, SpriteComponent>();
|
||||
while (query.MoveNext(out var uid, out var comp, out var sprite))
|
||||
{
|
||||
if (!sprite.LayerMapTryGet(ClockVisualLayers.HourHand, out var hourLayer) ||
|
||||
!sprite.LayerMapTryGet(ClockVisualLayers.MinuteHand, out var minuteLayer))
|
||||
if (!_sprite.LayerMapTryGet((uid, sprite), ClockVisualLayers.HourHand, out var hourLayer, false) ||
|
||||
!_sprite.LayerMapTryGet((uid, sprite), ClockVisualLayers.MinuteHand, out var minuteLayer, false))
|
||||
continue;
|
||||
|
||||
var time = GetClockTime((uid, comp));
|
||||
var hourState = $"{comp.HoursBase}{time.Hours % 12}";
|
||||
var minuteState = $"{comp.MinutesBase}{time.Minutes / 5}";
|
||||
sprite.LayerSetState(hourLayer, hourState);
|
||||
sprite.LayerSetState(minuteLayer, minuteState);
|
||||
_sprite.LayerSetRsiState((uid, sprite), hourLayer, hourState);
|
||||
_sprite.LayerSetRsiState((uid, sprite), minuteLayer, minuteState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
[Dependency] private readonly IResourceCache _cache = default!;
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||
[Dependency] private readonly DisplacementMapSystem _displacement = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly TagSystem _tagSystem = default!;
|
||||
|
||||
|
|
@ -82,10 +83,10 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
UpdateAllSlots(uid, component);
|
||||
|
||||
// No clothing equipped -> make sure the layer is hidden, though this should already be handled by on-unequip.
|
||||
if (args.Sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var layer))
|
||||
if (_sprite.LayerMapTryGet((uid, args.Sprite), HumanoidVisualLayers.StencilMask, out var layer, false))
|
||||
{
|
||||
DebugTools.Assert(!args.Sprite[layer].Visible);
|
||||
args.Sprite.LayerSetVisible(layer, false);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -214,9 +215,9 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
RenderEquipment(uid, item, clothing.InSlot, component, null, clothing);
|
||||
}
|
||||
|
||||
private void OnDidUnequip(EntityUid uid, SpriteComponent component, DidUnequipEvent args)
|
||||
private void OnDidUnequip(Entity<SpriteComponent> entity, ref DidUnequipEvent args)
|
||||
{
|
||||
if (!TryComp(uid, out InventorySlotsComponent? inventorySlots))
|
||||
if (!TryComp(entity, out InventorySlotsComponent? inventorySlots))
|
||||
return;
|
||||
|
||||
if (!inventorySlots.VisualLayerKeys.TryGetValue(args.Slot, out var revealedLayers))
|
||||
|
|
@ -226,7 +227,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
// may eventually bloat the player with lots of invisible layers.
|
||||
foreach (var layer in revealedLayers)
|
||||
{
|
||||
component.RemoveLayer(layer);
|
||||
_sprite.RemoveLayer(entity.AsNullable(), layer);
|
||||
}
|
||||
revealedLayers.Clear();
|
||||
}
|
||||
|
|
@ -269,7 +270,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
{
|
||||
foreach (var key in revealedLayers)
|
||||
{
|
||||
sprite.RemoveLayer(key);
|
||||
_sprite.RemoveLayer((equipee, sprite), key);
|
||||
}
|
||||
revealedLayers.Clear();
|
||||
}
|
||||
|
|
@ -290,7 +291,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
|
||||
// temporary, until layer draw depths get added. Basically: a layer with the key "slot" is being used as a
|
||||
// bookmark to determine where in the list of layers we should insert the clothing layers.
|
||||
bool slotLayerExists = sprite.LayerMapTryGet(slot, out var index);
|
||||
var slotLayerExists = _sprite.LayerMapTryGet((equipee, sprite), slot, out var index, false);
|
||||
|
||||
// Select displacement maps
|
||||
var displacementData = inventory.Displacements.GetValueOrDefault(slot); //Default unsexed map
|
||||
|
|
@ -348,16 +349,16 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
{
|
||||
index++;
|
||||
// note that every insertion requires reshuffling & remapping all the existing layers.
|
||||
sprite.AddBlankLayer(index);
|
||||
sprite.LayerMapSet(key, index);
|
||||
_sprite.AddBlankLayer((equipee, sprite), index);
|
||||
_sprite.LayerMapSet((equipee, sprite), key, index);
|
||||
|
||||
if (layerData.Color != null)
|
||||
sprite.LayerSetColor(key, layerData.Color.Value);
|
||||
_sprite.LayerSetColor((equipee, sprite), key, layerData.Color.Value);
|
||||
if (layerData.Scale != null)
|
||||
sprite.LayerSetScale(key, layerData.Scale.Value);
|
||||
_sprite.LayerSetScale((equipee, sprite), key, layerData.Scale.Value);
|
||||
}
|
||||
else
|
||||
index = sprite.LayerMapReserveBlank(key);
|
||||
index = _sprite.LayerMapReserve((equipee, sprite), key);
|
||||
|
||||
if (sprite[index] is not Layer layer)
|
||||
continue;
|
||||
|
|
@ -368,11 +369,11 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
&& layer.RSI == null
|
||||
&& TryComp(equipment, out SpriteComponent? clothingSprite))
|
||||
{
|
||||
layer.SetRsi(clothingSprite.BaseRSI);
|
||||
_sprite.LayerSetRsi(layer, clothingSprite.BaseRSI);
|
||||
}
|
||||
|
||||
sprite.LayerSetData(index, layerData);
|
||||
layer.Offset += slotDef.Offset;
|
||||
_sprite.LayerSetData((equipee, sprite), index, layerData);
|
||||
_sprite.LayerSetOffset(layer, layer.Offset + slotDef.Offset);
|
||||
|
||||
if (displacementData is not null)
|
||||
{
|
||||
|
|
@ -381,7 +382,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
|| bodyTypeName is not null && layerData.State.EndsWith(bodyTypeName)))
|
||||
continue;
|
||||
|
||||
if (_displacement.TryAddDisplacement(displacementData, sprite, index, key, out var displacementKey))
|
||||
if (_displacement.TryAddDisplacement(displacementData, (equipee, sprite), index, key, out var displacementKey))
|
||||
{
|
||||
revealedLayers.Add(displacementKey);
|
||||
index++;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public sealed class FlippableClothingVisualizerSystem : VisualizerSystem<Flippab
|
|||
|
||||
if (clothing.MappedLayer == null ||
|
||||
!AppearanceSystem.TryGetData<bool>(ent, FoldableSystem.FoldedVisuals.State, out var folding) ||
|
||||
!sprite.LayerMapTryGet(folding ? ent.Comp.FoldingLayer : ent.Comp.UnfoldingLayer, out var idx))
|
||||
!SpriteSystem.LayerMapTryGet((ent.Owner, sprite), folding ? ent.Comp.FoldingLayer : ent.Comp.UnfoldingLayer, out var idx, false))
|
||||
return;
|
||||
|
||||
// add each layer to the visuals
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@ namespace Content.Client.Clothing.Systems;
|
|||
public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IComponentFactory _factory = default!;
|
||||
[Dependency] private readonly EntityManager _entManager = default!;
|
||||
|
||||
private static readonly SlotFlags[] IgnoredSlots =
|
||||
{
|
||||
|
|
@ -49,7 +47,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
|
|||
{
|
||||
base.UpdateSprite(uid, proto);
|
||||
if (TryComp(uid, out SpriteComponent? sprite)
|
||||
&& proto.TryGetComponent(out SpriteComponent? otherSprite, _factory))
|
||||
&& proto.TryGetComponent(out SpriteComponent? otherSprite, Factory))
|
||||
{
|
||||
sprite.CopyFrom(otherSprite);
|
||||
}
|
||||
|
|
@ -65,14 +63,14 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
|
|||
return;
|
||||
|
||||
if (TryComp(helmet.ClothingUid, out SpriteComponent? helmetSprite)
|
||||
&& prototypeHelmetOther.TryGetComponent(out SpriteComponent? otherHelmetSprite, _factory))
|
||||
&& prototypeHelmetOther.TryGetComponent(out SpriteComponent? otherHelmetSprite, Factory))
|
||||
{
|
||||
helmetSprite.CopyFrom(otherHelmetSprite);
|
||||
}
|
||||
// Sunrise-end
|
||||
// Edgecase for PDAs to include visuals when UI is open
|
||||
if (TryComp(uid, out PdaBorderColorComponent? borderColor)
|
||||
&& proto.TryGetComponent(out PdaBorderColorComponent? otherBorderColor, _factory))
|
||||
&& proto.TryGetComponent(out PdaBorderColorComponent? otherBorderColor, Factory))
|
||||
{
|
||||
borderColor.BorderColor = otherBorderColor.BorderColor;
|
||||
borderColor.AccentHColor = otherBorderColor.AccentHColor;
|
||||
|
|
@ -106,7 +104,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
|
|||
// check if this is valid clothing
|
||||
if (!IsValidTarget(proto))
|
||||
continue;
|
||||
if (!proto.TryGetComponent(out ClothingComponent? item, _factory))
|
||||
if (!proto.TryGetComponent(out ClothingComponent? item, Factory))
|
||||
continue;
|
||||
|
||||
// sort item by their slot flags
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ namespace Content.Client.Clothing.UI;
|
|||
[UsedImplicitly]
|
||||
public sealed class ChameleonBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IComponentFactory _factory = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
private readonly ChameleonClothingSystem _chameleon;
|
||||
private readonly TagSystem _tag;
|
||||
|
|
@ -49,7 +48,7 @@ public sealed class ChameleonBoundUserInterface : BoundUserInterface
|
|||
if (string.IsNullOrEmpty(target) || !_proto.TryIndex(target, out EntityPrototype? proto))
|
||||
continue;
|
||||
|
||||
if (!proto.TryGetComponent(out TagComponent? tag, _factory) || !_tag.HasTag(tag, st.RequiredTag))
|
||||
if (!proto.TryGetComponent(out TagComponent? tag, EntMan.ComponentFactory) || !_tag.HasTag(tag, st.RequiredTag))
|
||||
continue;
|
||||
|
||||
newTargets.Add(target);
|
||||
|
|
|
|||
|
|
@ -18,23 +18,19 @@ public sealed class HideMechanismsCommand : LocalizedCommands
|
|||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var containerSys = _entityManager.System<SharedContainerSystem>();
|
||||
var query = _entityManager.AllEntityQueryEnumerator<OrganComponent>();
|
||||
var spriteSys = _entityManager.System<SpriteSystem>();
|
||||
var query = _entityManager.AllEntityQueryEnumerator<OrganComponent, SpriteComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _))
|
||||
while (query.MoveNext(out var uid, out _, out var sprite))
|
||||
{
|
||||
if (!_entityManager.TryGetComponent(uid, out SpriteComponent? sprite))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sprite.ContainerOccluded = false;
|
||||
spriteSys.SetContainerOccluded((uid, sprite), false);
|
||||
|
||||
var tempParent = uid;
|
||||
while (containerSys.TryGetContainingContainer((tempParent, null, null), out var container))
|
||||
{
|
||||
if (!container.ShowContents)
|
||||
{
|
||||
sprite.ContainerOccluded = true;
|
||||
spriteSys.SetContainerOccluded((uid, sprite), true);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,12 @@ public sealed class ShowMechanismsCommand : LocalizedCommands
|
|||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var spriteSys = _entManager.System<SpriteSystem>();
|
||||
var query = _entManager.AllEntityQueryEnumerator<OrganComponent, SpriteComponent>();
|
||||
|
||||
while (query.MoveNext(out _, out var sprite))
|
||||
while (query.MoveNext(out var uid, out _, out var sprite))
|
||||
{
|
||||
sprite.ContainerOccluded = false;
|
||||
spriteSys.SetContainerOccluded((uid, sprite), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ namespace Content.Client.Construction
|
|||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examineSystem = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
|
||||
private readonly Dictionary<int, EntityUid> _ghosts = new();
|
||||
|
|
@ -293,14 +294,14 @@ namespace Content.Client.Construction
|
|||
_ghosts.Add(comp.GhostId, ghost.Value);
|
||||
|
||||
var sprite = EntityManager.GetComponent<SpriteComponent>(ghost.Value);
|
||||
sprite.Color = new Color(48, 255, 48, 128);
|
||||
_sprite.SetColor((ghost.Value, sprite), new Color(48, 255, 48, 128));
|
||||
|
||||
if (targetProto.TryGetComponent(out IconComponent? icon, EntityManager.ComponentFactory))
|
||||
{
|
||||
sprite.AddBlankLayer(0);
|
||||
sprite.LayerSetSprite(0, icon.Icon);
|
||||
_sprite.AddBlankLayer((ghost.Value, sprite), 0);
|
||||
_sprite.LayerSetSprite((ghost.Value, sprite), 0, icon.Icon);
|
||||
sprite.LayerSetShader(0, "unshaded");
|
||||
sprite.LayerSetVisible(0, true);
|
||||
_sprite.LayerSetVisible((ghost.Value, sprite), 0, true);
|
||||
}
|
||||
else if (targetProto.Components.TryGetValue("Sprite", out _))
|
||||
{
|
||||
|
|
@ -318,10 +319,10 @@ namespace Content.Client.Construction
|
|||
state.StateId.Name is null)
|
||||
continue;
|
||||
|
||||
sprite.AddBlankLayer(i);
|
||||
sprite.LayerSetSprite(i, new SpriteSpecifier.Rsi(rsi.Path, state.StateId.Name));
|
||||
_sprite.AddBlankLayer((ghost.Value, sprite), i);
|
||||
_sprite.LayerSetSprite((ghost.Value, sprite), i, new SpriteSpecifier.Rsi(rsi.Path, state.StateId.Name));
|
||||
sprite.LayerSetShader(i, "unshaded");
|
||||
sprite.LayerSetVisible(i, true);
|
||||
_sprite.LayerSetVisible((ghost.Value, sprite), i, true);
|
||||
}
|
||||
|
||||
EntityManager.DeleteEntity(dummy);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ namespace Content.Client.Construction;
|
|||
public sealed class FlatpackSystem : SharedFlatpackSystem
|
||||
{
|
||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
|
|
@ -43,6 +44,6 @@ public sealed class FlatpackSystem : SharedFlatpackSystem
|
|||
}
|
||||
|
||||
if (color != null)
|
||||
args.Sprite.LayerSetColor(FlatpackVisualLayers.Overlay, color.Value);
|
||||
_sprite.LayerSetColor((ent.Owner, args.Sprite), FlatpackVisualLayers.Overlay, color.Value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Client.Lobby;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Client.UserInterface.Systems.MenuBar.Widgets;
|
||||
using Content.Shared.Construction.Prototypes;
|
||||
|
|
@ -28,6 +29,7 @@ namespace Content.Client.Construction.UI
|
|||
[Dependency] private readonly IPlacementManager _placementManager = default!;
|
||||
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IClientPreferencesManager _preferencesManager = default!;
|
||||
private readonly SpriteSystem _spriteSystem;
|
||||
|
||||
private readonly IConstructionMenuView _constructionView;
|
||||
|
|
@ -116,7 +118,7 @@ namespace Content.Client.Construction.UI
|
|||
|
||||
_constructionView.RecipeFavorited += (_, _) => OnViewFavoriteRecipe();
|
||||
|
||||
PopulateCategories();
|
||||
SetFavorites(_preferencesManager.Preferences?.ConstructionFavorites ?? []);
|
||||
OnViewPopulateRecipes(_constructionView, (string.Empty, string.Empty));
|
||||
}
|
||||
|
||||
|
|
@ -493,10 +495,34 @@ namespace Content.Client.Construction.UI
|
|||
_favoritedRecipes.Count > 0 ? (string.Empty, FavoriteCatName) : (string.Empty, string.Empty));
|
||||
}
|
||||
|
||||
var newFavorites = new List<ProtoId<ConstructionPrototype>>(_favoritedRecipes.Count);
|
||||
foreach (var recipe in _favoritedRecipes)
|
||||
newFavorites.Add(recipe.ID);
|
||||
|
||||
_preferencesManager.UpdateConstructionFavorites(newFavorites);
|
||||
PopulateInfo(_selected);
|
||||
PopulateCategories(_selectedCategory);
|
||||
}
|
||||
|
||||
public void SetFavorites(IReadOnlyList<ProtoId<ConstructionPrototype>> favorites)
|
||||
{
|
||||
_favoritedRecipes.Clear();
|
||||
|
||||
foreach (var id in favorites)
|
||||
{
|
||||
if (_prototypeManager.TryIndex(id, out ConstructionPrototype? recipe, logError: false))
|
||||
_favoritedRecipes.Add(recipe);
|
||||
}
|
||||
|
||||
if (_selectedCategory == FavoriteCatName)
|
||||
{
|
||||
OnViewPopulateRecipes(_constructionView,
|
||||
_favoritedRecipes.Count > 0 ? (string.Empty, FavoriteCatName) : (string.Empty, string.Empty));
|
||||
}
|
||||
|
||||
PopulateCategories(_selectedCategory);
|
||||
}
|
||||
|
||||
private void SystemBindingChanged(ConstructionSystem? newSystem)
|
||||
{
|
||||
if (newSystem is null)
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@ using Content.Shared.Cuffs.Components;
|
|||
using Content.Shared.Humanoid;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Cuffs;
|
||||
|
||||
public sealed class CuffableSystem : SharedCuffableSystem
|
||||
{
|
||||
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -22,7 +24,7 @@ public sealed class CuffableSystem : SharedCuffableSystem
|
|||
private void OnCuffableShutdown(EntityUid uid, CuffableComponent component, ComponentShutdown args)
|
||||
{
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite))
|
||||
sprite.LayerSetVisible(HumanoidVisualLayers.Handcuffs, false);
|
||||
_sprite.LayerSetVisible((uid, sprite), HumanoidVisualLayers.Handcuffs, false);
|
||||
}
|
||||
|
||||
private void OnCuffableHandleState(EntityUid uid, CuffableComponent component, ref ComponentHandleState args)
|
||||
|
|
@ -39,22 +41,22 @@ public sealed class CuffableSystem : SharedCuffableSystem
|
|||
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
||||
return;
|
||||
var cuffed = cuffState.NumHandsCuffed > 0;
|
||||
sprite.LayerSetVisible(HumanoidVisualLayers.Handcuffs, cuffed);
|
||||
_sprite.LayerSetVisible((uid, sprite), HumanoidVisualLayers.Handcuffs, cuffed);
|
||||
|
||||
// if they are not cuffed, that means that we didn't get a valid color,
|
||||
// iconstate, or RSI. that also means we don't need to update the sprites.
|
||||
if (!cuffed)
|
||||
return;
|
||||
sprite.LayerSetColor(HumanoidVisualLayers.Handcuffs, cuffState.Color!.Value);
|
||||
_sprite.LayerSetColor((uid, sprite), HumanoidVisualLayers.Handcuffs, cuffState.Color!.Value);
|
||||
|
||||
if (!Equals(component.CurrentRSI, cuffState.RSI) && cuffState.RSI != null) // we don't want to keep loading the same RSI
|
||||
{
|
||||
component.CurrentRSI = cuffState.RSI;
|
||||
sprite.LayerSetState(HumanoidVisualLayers.Handcuffs, cuffState.IconState, component.CurrentRSI);
|
||||
_sprite.LayerSetRsi((uid, sprite), _sprite.LayerMapGet((uid, sprite), HumanoidVisualLayers.Handcuffs), new ResPath(component.CurrentRSI), cuffState.IconState);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.LayerSetState(HumanoidVisualLayers.Handcuffs, cuffState.IconState);
|
||||
_sprite.LayerSetRsiState((uid, sprite), HumanoidVisualLayers.Handcuffs, cuffState.IconState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
// the layer key just doesn't exist, we skip it.
|
||||
foreach (var key in damageVisComp.TargetLayers)
|
||||
{
|
||||
if (!spriteComponent.LayerMapTryGet(key, out var index))
|
||||
if (!SpriteSystem.LayerMapTryGet((entity, spriteComponent), key, out var index, false))
|
||||
{
|
||||
Log.Warning($"Layer at key {key} was invalid for entity {entity}.");
|
||||
continue;
|
||||
|
|
@ -253,7 +253,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
foreach (var layer in damageVisComp.TargetLayerMapKeys)
|
||||
{
|
||||
var layerCount = spriteComponent.AllLayers.Count();
|
||||
var index = spriteComponent.LayerMapGet(layer);
|
||||
var index = SpriteSystem.LayerMapGet((entity, spriteComponent), layer);
|
||||
// var layerState = spriteComponent.LayerGetState(index).ToString()!;
|
||||
|
||||
if (index + 1 != layerCount)
|
||||
|
|
@ -269,7 +269,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
{
|
||||
foreach (var (group, sprite) in damageVisComp.DamageOverlayGroups)
|
||||
{
|
||||
AddDamageLayerToSprite(spriteComponent,
|
||||
AddDamageLayerToSprite((entity, spriteComponent),
|
||||
sprite,
|
||||
$"{layer}_{group}_{damageVisComp.Thresholds[1]}",
|
||||
$"{layer}{group}",
|
||||
|
|
@ -283,7 +283,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
// was taken.
|
||||
else if (damageVisComp.DamageOverlay != null)
|
||||
{
|
||||
AddDamageLayerToSprite(spriteComponent,
|
||||
AddDamageLayerToSprite((entity, spriteComponent),
|
||||
damageVisComp.DamageOverlay,
|
||||
$"{layer}_{damageVisComp.Thresholds[1]}",
|
||||
$"{layer}trackDamage",
|
||||
|
|
@ -301,7 +301,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
{
|
||||
foreach (var (group, sprite) in damageVisComp.DamageOverlayGroups)
|
||||
{
|
||||
AddDamageLayerToSprite(spriteComponent,
|
||||
AddDamageLayerToSprite((entity, spriteComponent),
|
||||
sprite,
|
||||
$"DamageOverlay_{group}_{damageVisComp.Thresholds[1]}",
|
||||
$"DamageOverlay{group}");
|
||||
|
|
@ -310,7 +310,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
}
|
||||
else if (damageVisComp.DamageOverlay != null)
|
||||
{
|
||||
AddDamageLayerToSprite(spriteComponent,
|
||||
AddDamageLayerToSprite((entity, spriteComponent),
|
||||
damageVisComp.DamageOverlay,
|
||||
$"DamageOverlay_{damageVisComp.Thresholds[1]}",
|
||||
"DamageOverlay");
|
||||
|
|
@ -322,16 +322,19 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
/// <summary>
|
||||
/// Adds a damage tracking layer to a given sprite component.
|
||||
/// </summary>
|
||||
private void AddDamageLayerToSprite(SpriteComponent spriteComponent, DamageVisualizerSprite sprite, string state, string mapKey, int? index = null)
|
||||
private void AddDamageLayerToSprite(Entity<SpriteComponent?> spriteEnt, DamageVisualizerSprite sprite, string state, string mapKey, int? index = null)
|
||||
{
|
||||
var newLayer = spriteComponent.AddLayer(
|
||||
var newLayer = SpriteSystem.AddLayer(
|
||||
spriteEnt,
|
||||
new SpriteSpecifier.Rsi(
|
||||
new (sprite.Sprite), state
|
||||
), index);
|
||||
spriteComponent.LayerMapSet(mapKey, newLayer);
|
||||
new(sprite.Sprite), state
|
||||
),
|
||||
index
|
||||
);
|
||||
SpriteSystem.LayerMapSet(spriteEnt, mapKey, newLayer);
|
||||
if (sprite.Color != null)
|
||||
spriteComponent.LayerSetColor(newLayer, Color.FromHex(sprite.Color));
|
||||
spriteComponent.LayerSetVisible(newLayer, false);
|
||||
SpriteSystem.LayerSetColor(spriteEnt, newLayer, Color.FromHex(sprite.Color));
|
||||
SpriteSystem.LayerSetVisible(spriteEnt, newLayer, false);
|
||||
}
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, DamageVisualsComponent damageVisComp, ref AppearanceChangeEvent args)
|
||||
|
|
@ -362,18 +365,18 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
UpdateDisabledLayers(uid, spriteComponent, component, damageVisComp);
|
||||
|
||||
if (damageVisComp.Overlay && damageVisComp.DamageOverlayGroups != null && damageVisComp.TargetLayers == null)
|
||||
CheckOverlayOrdering(spriteComponent, damageVisComp);
|
||||
CheckOverlayOrdering((uid, spriteComponent), damageVisComp);
|
||||
|
||||
if (AppearanceSystem.TryGetData<bool>(uid, DamageVisualizerKeys.ForceUpdate, out var update, component)
|
||||
&& update)
|
||||
{
|
||||
ForceUpdateLayers(damageComponent, spriteComponent, damageVisComp);
|
||||
ForceUpdateLayers((uid, damageComponent, spriteComponent, damageVisComp));
|
||||
return;
|
||||
}
|
||||
|
||||
if (damageVisComp.TrackAllDamage)
|
||||
{
|
||||
UpdateDamageVisuals(damageComponent, spriteComponent, damageVisComp);
|
||||
UpdateDamageVisuals((uid, damageComponent, spriteComponent, damageVisComp));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -383,7 +386,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
data = new DamageVisualizerGroupData(Comp<DamageableComponent>(uid).DamagePerGroup.Keys.ToList());
|
||||
}
|
||||
|
||||
UpdateDamageVisuals(data.GroupList, damageComponent, spriteComponent, damageVisComp);
|
||||
UpdateDamageVisuals(data.GroupList, (uid, damageComponent, spriteComponent, damageVisComp));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -406,7 +409,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
damageVisComp.DisabledLayers[layer] = disabled;
|
||||
if (damageVisComp.TrackAllDamage)
|
||||
{
|
||||
spriteComponent.LayerSetVisible($"{layer}trackDamage", !disabled);
|
||||
SpriteSystem.LayerSetVisible((uid, spriteComponent), $"{layer}trackDamage", !disabled);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -415,7 +418,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
|
||||
foreach (var damageGroup in damageVisComp.DamageOverlayGroups.Keys)
|
||||
{
|
||||
spriteComponent.LayerSetVisible($"{layer}{damageGroup}", !disabled);
|
||||
SpriteSystem.LayerSetVisible((uid, spriteComponent), $"{layer}{damageGroup}", !disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -427,16 +430,16 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
/// most layer doesn't match, the sprite
|
||||
/// layers are recreated and placed on top.
|
||||
/// </summary>
|
||||
private void CheckOverlayOrdering(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
|
||||
private void CheckOverlayOrdering(Entity<SpriteComponent> spriteEnt, DamageVisualsComponent damageVisComp)
|
||||
{
|
||||
if (spriteComponent[damageVisComp.TopMostLayerKey] != spriteComponent[spriteComponent.AllLayers.Count() - 1])
|
||||
if (spriteEnt.Comp[damageVisComp.TopMostLayerKey] != spriteEnt.Comp[spriteEnt.Comp.AllLayers.Count() - 1])
|
||||
{
|
||||
if (!damageVisComp.TrackAllDamage && damageVisComp.DamageOverlayGroups != null)
|
||||
{
|
||||
foreach (var (damageGroup, sprite) in damageVisComp.DamageOverlayGroups)
|
||||
{
|
||||
var threshold = damageVisComp.LastThresholdPerGroup[damageGroup];
|
||||
ReorderOverlaySprite(spriteComponent,
|
||||
ReorderOverlaySprite(spriteEnt,
|
||||
damageVisComp,
|
||||
sprite,
|
||||
$"DamageOverlay{damageGroup}",
|
||||
|
|
@ -446,7 +449,7 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
}
|
||||
else if (damageVisComp.TrackAllDamage && damageVisComp.DamageOverlay != null)
|
||||
{
|
||||
ReorderOverlaySprite(spriteComponent,
|
||||
ReorderOverlaySprite(spriteEnt,
|
||||
damageVisComp,
|
||||
damageVisComp.DamageOverlay,
|
||||
$"DamageOverlay",
|
||||
|
|
@ -456,21 +459,22 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
}
|
||||
}
|
||||
|
||||
private void ReorderOverlaySprite(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, DamageVisualizerSprite sprite, string key, string statePrefix, FixedPoint2 threshold)
|
||||
private void ReorderOverlaySprite(Entity<SpriteComponent> spriteEnt, DamageVisualsComponent damageVisComp, DamageVisualizerSprite sprite, string key, string statePrefix, FixedPoint2 threshold)
|
||||
{
|
||||
spriteComponent.LayerMapTryGet(key, out var spriteLayer);
|
||||
var visibility = spriteComponent[spriteLayer].Visible;
|
||||
spriteComponent.RemoveLayer(spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet(spriteEnt.AsNullable(), key, out var spriteLayer, false);
|
||||
var visibility = spriteEnt.Comp[spriteLayer].Visible;
|
||||
SpriteSystem.RemoveLayer(spriteEnt.AsNullable(), spriteLayer);
|
||||
if (threshold == FixedPoint2.Zero) // these should automatically be invisible
|
||||
threshold = damageVisComp.Thresholds[1];
|
||||
spriteLayer = spriteComponent.AddLayer(
|
||||
spriteLayer = SpriteSystem.AddLayer(
|
||||
spriteEnt.AsNullable(),
|
||||
new SpriteSpecifier.Rsi(
|
||||
new (sprite.Sprite),
|
||||
new(sprite.Sprite),
|
||||
$"{statePrefix}_{threshold}"
|
||||
),
|
||||
spriteLayer);
|
||||
spriteComponent.LayerMapSet(key, spriteLayer);
|
||||
spriteComponent.LayerSetVisible(spriteLayer, visibility);
|
||||
SpriteSystem.LayerMapSet(spriteEnt.AsNullable(), key, spriteLayer);
|
||||
SpriteSystem.LayerSetVisible(spriteEnt.AsNullable(), spriteLayer, visibility);
|
||||
// this is somewhat iffy since it constantly reallocates
|
||||
damageVisComp.TopMostLayerKey = key;
|
||||
}
|
||||
|
|
@ -479,8 +483,12 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
/// Updates damage visuals without tracking
|
||||
/// any damage groups.
|
||||
/// </summary>
|
||||
private void UpdateDamageVisuals(DamageableComponent damageComponent, SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
|
||||
private void UpdateDamageVisuals(Entity<DamageableComponent, SpriteComponent, DamageVisualsComponent> entity)
|
||||
{
|
||||
var damageComponent = entity.Comp1;
|
||||
var spriteComponent = entity.Comp2;
|
||||
var damageVisComp = entity.Comp3;
|
||||
|
||||
if (!CheckThresholdBoundary(damageComponent.TotalDamage, damageVisComp.LastDamageThreshold, damageVisComp, out var threshold))
|
||||
return;
|
||||
|
||||
|
|
@ -490,12 +498,12 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
{
|
||||
foreach (var layerMapKey in damageVisComp.TargetLayerMapKeys)
|
||||
{
|
||||
UpdateTargetLayer(spriteComponent, damageVisComp, layerMapKey, threshold);
|
||||
UpdateTargetLayer((entity, spriteComponent), damageVisComp, layerMapKey, threshold);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateOverlay(spriteComponent, threshold);
|
||||
UpdateOverlay((entity, spriteComponent), threshold);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -504,8 +512,12 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
/// according to the list of damage groups
|
||||
/// passed into it.
|
||||
/// </summary>
|
||||
private void UpdateDamageVisuals(List<string> delta, DamageableComponent damageComponent, SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
|
||||
private void UpdateDamageVisuals(List<string> delta, Entity<DamageableComponent, SpriteComponent, DamageVisualsComponent> entity)
|
||||
{
|
||||
var damageComponent = entity.Comp1;
|
||||
var spriteComponent = entity.Comp2;
|
||||
var damageVisComp = entity.Comp3;
|
||||
|
||||
foreach (var damageGroup in delta)
|
||||
{
|
||||
if (!damageVisComp.Overlay && damageGroup != damageVisComp.DamageGroup)
|
||||
|
|
@ -525,12 +537,12 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
{
|
||||
foreach (var layerMapKey in damageVisComp.TargetLayerMapKeys)
|
||||
{
|
||||
UpdateTargetLayer(spriteComponent, damageVisComp, layerMapKey, damageGroup, threshold);
|
||||
UpdateTargetLayer((entity, spriteComponent, damageVisComp), layerMapKey, damageGroup, threshold);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateOverlay(spriteComponent, damageVisComp, damageGroup, threshold);
|
||||
UpdateOverlay((entity, spriteComponent, damageVisComp), damageGroup, threshold);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -567,19 +579,21 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
/// Does different things depending on
|
||||
/// the configuration of the visualizer.
|
||||
/// </summary>
|
||||
private void ForceUpdateLayers(DamageableComponent damageComponent, SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
|
||||
private void ForceUpdateLayers(Entity<DamageableComponent, SpriteComponent, DamageVisualsComponent> entity)
|
||||
{
|
||||
var damageVisComp = entity.Comp3;
|
||||
|
||||
if (damageVisComp.DamageOverlayGroups != null)
|
||||
{
|
||||
UpdateDamageVisuals(damageVisComp.DamageOverlayGroups.Keys.ToList(), damageComponent, spriteComponent, damageVisComp);
|
||||
UpdateDamageVisuals(damageVisComp.DamageOverlayGroups.Keys.ToList(), entity);
|
||||
}
|
||||
else if (damageVisComp.DamageGroup != null)
|
||||
{
|
||||
UpdateDamageVisuals(new List<string>(){ damageVisComp.DamageGroup }, damageComponent, spriteComponent, damageVisComp);
|
||||
UpdateDamageVisuals(new List<string>() { damageVisComp.DamageGroup }, entity);
|
||||
}
|
||||
else if (damageVisComp.DamageOverlay != null)
|
||||
{
|
||||
UpdateDamageVisuals(damageComponent, spriteComponent, damageVisComp);
|
||||
UpdateDamageVisuals(entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -588,16 +602,16 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
/// it assumes you're updating a layer that is tracking all
|
||||
/// damage.
|
||||
/// </summary>
|
||||
private void UpdateTargetLayer(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, object layerMapKey, FixedPoint2 threshold)
|
||||
private void UpdateTargetLayer(Entity<SpriteComponent> spriteEnt, DamageVisualsComponent damageVisComp, object layerMapKey, FixedPoint2 threshold)
|
||||
{
|
||||
if (damageVisComp.Overlay && damageVisComp.DamageOverlayGroups != null)
|
||||
{
|
||||
if (!damageVisComp.DisabledLayers[layerMapKey])
|
||||
{
|
||||
var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
|
||||
spriteComponent.LayerMapTryGet($"{layerMapKey}trackDamage", out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet(spriteEnt.AsNullable(), $"{layerMapKey}trackDamage", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(spriteEnt,
|
||||
spriteLayer,
|
||||
$"{layerState}",
|
||||
threshold);
|
||||
|
|
@ -606,9 +620,9 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
else if (!damageVisComp.Overlay)
|
||||
{
|
||||
var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
|
||||
spriteComponent.LayerMapTryGet(layerMapKey, out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet(spriteEnt.AsNullable(), $"{layerMapKey}", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(spriteEnt,
|
||||
spriteLayer,
|
||||
$"{layerState}",
|
||||
threshold);
|
||||
|
|
@ -618,16 +632,20 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
/// <summary>
|
||||
/// Updates a target layer by damage group.
|
||||
/// </summary>
|
||||
private void UpdateTargetLayer(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, object layerMapKey, string damageGroup, FixedPoint2 threshold)
|
||||
private void UpdateTargetLayer(Entity<SpriteComponent, DamageVisualsComponent> entity, object layerMapKey, string damageGroup, FixedPoint2 threshold)
|
||||
{
|
||||
var spriteComponent = entity.Comp1;
|
||||
var damageVisComp = entity.Comp2;
|
||||
|
||||
if (damageVisComp.Overlay && damageVisComp.DamageOverlayGroups != null)
|
||||
{
|
||||
if (damageVisComp.DamageOverlayGroups.ContainsKey(damageGroup) && !damageVisComp.DisabledLayers[layerMapKey])
|
||||
{
|
||||
var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
|
||||
spriteComponent.LayerMapTryGet($"{layerMapKey}{damageGroup}", out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet((entity, spriteComponent), $"{layerMapKey}{damageGroup}", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(
|
||||
(entity, spriteComponent),
|
||||
spriteLayer,
|
||||
$"{layerState}_{damageGroup}",
|
||||
threshold);
|
||||
|
|
@ -636,9 +654,10 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
else if (!damageVisComp.Overlay)
|
||||
{
|
||||
var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
|
||||
spriteComponent.LayerMapTryGet(layerMapKey, out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet((entity, spriteComponent), $"{layerMapKey}", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(
|
||||
(entity, spriteComponent),
|
||||
spriteLayer,
|
||||
$"{layerState}_{damageGroup}",
|
||||
threshold);
|
||||
|
|
@ -648,11 +667,11 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
/// <summary>
|
||||
/// Updates an overlay that is tracking all damage.
|
||||
/// </summary>
|
||||
private void UpdateOverlay(SpriteComponent spriteComponent, FixedPoint2 threshold)
|
||||
private void UpdateOverlay(Entity<SpriteComponent> spriteEnt, FixedPoint2 threshold)
|
||||
{
|
||||
spriteComponent.LayerMapTryGet($"DamageOverlay", out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet(spriteEnt.AsNullable(), $"DamageOverlay", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(spriteEnt,
|
||||
spriteLayer,
|
||||
$"DamageOverlay",
|
||||
threshold);
|
||||
|
|
@ -661,15 +680,19 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
/// <summary>
|
||||
/// Updates an overlay based on damage group.
|
||||
/// </summary>
|
||||
private void UpdateOverlay(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, string damageGroup, FixedPoint2 threshold)
|
||||
private void UpdateOverlay(Entity<SpriteComponent, DamageVisualsComponent> entity, string damageGroup, FixedPoint2 threshold)
|
||||
{
|
||||
var spriteComponent = entity.Comp1;
|
||||
var damageVisComp = entity.Comp2;
|
||||
|
||||
if (damageVisComp.DamageOverlayGroups != null)
|
||||
{
|
||||
if (damageVisComp.DamageOverlayGroups.ContainsKey(damageGroup))
|
||||
{
|
||||
spriteComponent.LayerMapTryGet($"DamageOverlay{damageGroup}", out var spriteLayer);
|
||||
SpriteSystem.LayerMapTryGet((entity, spriteComponent), $"DamageOverlay{damageGroup}", out var spriteLayer, false);
|
||||
|
||||
UpdateDamageLayerState(spriteComponent,
|
||||
UpdateDamageLayerState(
|
||||
(entity, spriteComponent),
|
||||
spriteLayer,
|
||||
$"DamageOverlay_{damageGroup}",
|
||||
threshold);
|
||||
|
|
@ -683,19 +706,19 @@ public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponen
|
|||
/// function calls it), and what threshold
|
||||
/// was passed into it.
|
||||
/// </summary>
|
||||
private void UpdateDamageLayerState(SpriteComponent spriteComponent, int spriteLayer, string statePrefix, FixedPoint2 threshold)
|
||||
private void UpdateDamageLayerState(Entity<SpriteComponent> spriteEnt, int spriteLayer, string statePrefix, FixedPoint2 threshold)
|
||||
{
|
||||
if (threshold == 0)
|
||||
{
|
||||
spriteComponent.LayerSetVisible(spriteLayer, false);
|
||||
SpriteSystem.LayerSetVisible(spriteEnt.AsNullable(), spriteLayer, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!spriteComponent[spriteLayer].Visible)
|
||||
if (!spriteEnt.Comp[spriteLayer].Visible)
|
||||
{
|
||||
spriteComponent.LayerSetVisible(spriteLayer, true);
|
||||
SpriteSystem.LayerSetVisible(spriteEnt.AsNullable(), spriteLayer, true);
|
||||
}
|
||||
spriteComponent.LayerSetState(spriteLayer, $"{statePrefix}_{threshold}");
|
||||
SpriteSystem.LayerSetRsiState(spriteEnt.AsNullable(), spriteLayer, $"{statePrefix}_{threshold}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7
Content.Client/Damage/Systems/StaminaSystem.cs
Normal file
7
Content.Client/Damage/Systems/StaminaSystem.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
using Content.Shared.Damage.Systems;
|
||||
|
||||
namespace Content.Client.Damage.Systems;
|
||||
|
||||
public sealed partial class StaminaSystem : SharedStaminaSystem
|
||||
{
|
||||
}
|
||||
|
|
@ -21,34 +21,34 @@ public sealed class DamageStateVisualizerSystem : VisualizerSystem<DamageStateVi
|
|||
}
|
||||
|
||||
// Brain no worky rn so this was just easier.
|
||||
foreach (var key in new []{ DamageStateVisualLayers.Base, DamageStateVisualLayers.BaseUnshaded })
|
||||
foreach (var key in new[] { DamageStateVisualLayers.Base, DamageStateVisualLayers.BaseUnshaded })
|
||||
{
|
||||
if (!sprite.LayerMapTryGet(key, out _)) continue;
|
||||
if (!SpriteSystem.LayerMapTryGet((uid, sprite), key, out _, false)) continue;
|
||||
|
||||
sprite.LayerSetVisible(key, false);
|
||||
SpriteSystem.LayerSetVisible((uid, sprite), key, false);
|
||||
}
|
||||
|
||||
foreach (var (key, state) in layers)
|
||||
{
|
||||
// Inheritance moment.
|
||||
if (!sprite.LayerMapTryGet(key, out _)) continue;
|
||||
if (!SpriteSystem.LayerMapTryGet((uid, sprite), key, out _, false)) continue;
|
||||
|
||||
sprite.LayerSetVisible(key, true);
|
||||
sprite.LayerSetState(key, state);
|
||||
SpriteSystem.LayerSetVisible((uid, sprite), key, true);
|
||||
SpriteSystem.LayerSetRsiState((uid, sprite), key, state);
|
||||
}
|
||||
|
||||
// So they don't draw over mobs anymore
|
||||
if (data == MobState.Dead)
|
||||
{
|
||||
if (sprite.DrawDepth > (int) DrawDepth.DeadMobs)
|
||||
if (sprite.DrawDepth > (int)DrawDepth.DeadMobs)
|
||||
{
|
||||
component.OriginalDrawDepth = sprite.DrawDepth;
|
||||
sprite.DrawDepth = (int) DrawDepth.DeadMobs;
|
||||
SpriteSystem.SetDrawDepth((uid, sprite), (int)DrawDepth.DeadMobs);
|
||||
}
|
||||
}
|
||||
else if (component.OriginalDrawDepth != null)
|
||||
{
|
||||
sprite.DrawDepth = component.OriginalDrawDepth.Value;
|
||||
SpriteSystem.SetDrawDepth((uid, sprite), component.OriginalDrawDepth.Value);
|
||||
component.OriginalDrawDepth = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ public sealed class DeliveryVisualizerSystem : VisualizerSystem<DeliveryComponen
|
|||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private static readonly ProtoId<JobIconPrototype> UnknownIcon = "JobIconUnknown";
|
||||
|
||||
|
|
@ -25,11 +24,11 @@ public sealed class DeliveryVisualizerSystem : VisualizerSystem<DeliveryComponen
|
|||
|
||||
if (!_prototype.TryIndex<JobIconPrototype>(job, out var icon))
|
||||
{
|
||||
args.Sprite.LayerSetTexture(DeliveryVisualLayers.JobStamp, _sprite.Frame0(_prototype.Index("JobIconUnknown")));
|
||||
SpriteSystem.LayerSetTexture((uid, args.Sprite), DeliveryVisualLayers.JobStamp, SpriteSystem.Frame0(_prototype.Index("JobIconUnknown")));
|
||||
return;
|
||||
}
|
||||
|
||||
args.Sprite.LayerSetTexture(DeliveryVisualLayers.JobStamp, _sprite.Frame0(icon.Icon));
|
||||
SpriteSystem.LayerSetTexture((uid, args.Sprite), DeliveryVisualLayers.JobStamp, SpriteSystem.Frame0(icon.Icon));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,6 +41,8 @@ public enum DeliveryVisualLayers : byte
|
|||
PriorityTape,
|
||||
Breakage,
|
||||
Trash,
|
||||
Bomb,
|
||||
BombPrimed,
|
||||
}
|
||||
|
||||
public enum DeliverySpawnerVisualLayers : byte
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ namespace Content.Client.Dice;
|
|||
|
||||
public sealed class DiceSystem : SharedDiceSystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
|
@ -18,11 +20,11 @@ public sealed class DiceSystem : SharedDiceSystem
|
|||
return;
|
||||
|
||||
// TODO maybe just move each die to its own RSI?
|
||||
var state = sprite.LayerGetState(0).Name;
|
||||
var state = _sprite.LayerGetRsiState((entity.Owner, sprite), 0).Name;
|
||||
if (state == null)
|
||||
return;
|
||||
|
||||
var prefix = state.Substring(0, state.IndexOf('_'));
|
||||
sprite.LayerSetState(0, $"{prefix}_{entity.Comp.CurrentValue}");
|
||||
_sprite.LayerSetRsiState((entity.Owner, sprite), 0, $"{prefix}_{entity.Comp.CurrentValue}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,18 +8,19 @@ namespace Content.Client.DisplacementMap;
|
|||
public sealed class DisplacementMapSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ISerializationManager _serialization = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Attempting to apply a displacement map to a specific layer of SpriteComponent
|
||||
/// </summary>
|
||||
/// <param name="data">Information package for applying the displacement map</param>
|
||||
/// <param name="sprite">SpriteComponent</param>
|
||||
/// <param name="sprite">Entity with SpriteComponent</param>
|
||||
/// <param name="index">Index of the layer where the new map layer will be added</param>
|
||||
/// <param name="key">Unique layer key, which will determine which layer to apply displacement map to</param>
|
||||
/// <param name="displacementKey">The key of the new displacement map layer added by this function.</param>
|
||||
/// <returns></returns>
|
||||
public bool TryAddDisplacement(DisplacementData data,
|
||||
SpriteComponent sprite,
|
||||
Entity<SpriteComponent> sprite,
|
||||
int index,
|
||||
object key,
|
||||
out string displacementKey)
|
||||
|
|
@ -30,10 +31,9 @@ public sealed class DisplacementMapSystem : EntitySystem
|
|||
return false;
|
||||
|
||||
if (data.ShaderOverride != null)
|
||||
sprite.LayerSetShader(index, data.ShaderOverride);
|
||||
sprite.Comp.LayerSetShader(index, data.ShaderOverride);
|
||||
|
||||
if (sprite.LayerMapTryGet(displacementKey, out var oldIndex))
|
||||
sprite.RemoveLayer(oldIndex);
|
||||
_sprite.RemoveLayer(sprite.AsNullable(), displacementKey, false);
|
||||
|
||||
//allows you not to write it every time in the YML
|
||||
foreach (var pair in data.SizeMaps)
|
||||
|
|
@ -55,7 +55,7 @@ public sealed class DisplacementMapSystem : EntitySystem
|
|||
// We choose a displacement map from the possible ones, matching the size with the original layer size.
|
||||
// If there is no such a map, we use a standard 32 by 32 one
|
||||
var displacementDataLayer = data.SizeMaps[EyeManager.PixelsPerMeter];
|
||||
var actualRSI = sprite.LayerGetActualRSI(index);
|
||||
var actualRSI = _sprite.LayerGetEffectiveRsi(sprite.AsNullable(), index);
|
||||
if (actualRSI is not null)
|
||||
{
|
||||
if (actualRSI.Size.X != actualRSI.Size.Y)
|
||||
|
|
@ -72,9 +72,20 @@ public sealed class DisplacementMapSystem : EntitySystem
|
|||
var displacementLayer = _serialization.CreateCopy(displacementDataLayer, notNullableOverride: true);
|
||||
displacementLayer.CopyToShaderParameters!.LayerKey = key.ToString() ?? "this is impossible";
|
||||
|
||||
sprite.AddLayer(displacementLayer, index);
|
||||
sprite.LayerMapSet(displacementKey, index);
|
||||
_sprite.AddLayer(sprite.AsNullable(), displacementLayer, index);
|
||||
_sprite.LayerMapSet(sprite.AsNullable(), displacementKey, index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="TryAddDisplacement"/>
|
||||
[Obsolete("Use the Entity<SpriteComponent> overload")]
|
||||
public bool TryAddDisplacement(DisplacementData data,
|
||||
SpriteComponent sprite,
|
||||
int index,
|
||||
object key,
|
||||
out string displacementKey)
|
||||
{
|
||||
return TryAddDisplacement(data, (sprite.Owner, sprite), index, key, out displacementKey);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
|||
[Dependency] private readonly AnimationPlayerSystem _animationSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private const string AnimationKey = "disposal_unit_animation";
|
||||
|
||||
|
|
@ -67,13 +68,13 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
|||
if (!_appearanceSystem.TryGetData<DisposalUnitComponent.VisualState>(ent, DisposalUnitComponent.Visuals.VisualState, out var state, appearance))
|
||||
return;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.Unanchored, state == DisposalUnitComponent.VisualState.UnAnchored);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.Base, state == DisposalUnitComponent.VisualState.Anchored);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayFlush, state == DisposalUnitComponent.VisualState.OverlayFlushing);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.BaseCharging, state == DisposalUnitComponent.VisualState.OverlayCharging);
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.Unanchored, state == DisposalUnitComponent.VisualState.UnAnchored);
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.Base, state == DisposalUnitComponent.VisualState.Anchored);
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.OverlayFlush, state == DisposalUnitComponent.VisualState.OverlayFlushing);
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.BaseCharging, state == DisposalUnitComponent.VisualState.OverlayCharging);
|
||||
|
||||
var chargingState = sprite.LayerMapTryGet(DisposalUnitVisualLayers.BaseCharging, out var chargingLayer)
|
||||
? sprite.LayerGetState(chargingLayer)
|
||||
var chargingState = _sprite.LayerMapTryGet((ent, sprite), DisposalUnitVisualLayers.BaseCharging, out var chargingLayer, false)
|
||||
? _sprite.LayerGetRsiState((ent, sprite), chargingLayer)
|
||||
: new RSI.StateId(DefaultChargeState);
|
||||
|
||||
// This is a transient state so not too worried about replaying in range.
|
||||
|
|
@ -81,8 +82,8 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
|||
{
|
||||
if (!_animationSystem.HasRunningAnimation(ent, AnimationKey))
|
||||
{
|
||||
var flushState = sprite.LayerMapTryGet(DisposalUnitVisualLayers.OverlayFlush, out var flushLayer)
|
||||
? sprite.LayerGetState(flushLayer)
|
||||
var flushState = _sprite.LayerMapTryGet((ent, sprite), DisposalUnitVisualLayers.OverlayFlush, out var flushLayer, false)
|
||||
? _sprite.LayerGetRsiState((ent, sprite), flushLayer)
|
||||
: new RSI.StateId(DefaultFlushState);
|
||||
|
||||
// Setup the flush animation to play
|
||||
|
|
@ -124,16 +125,16 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
|||
if (!_appearanceSystem.TryGetData<DisposalUnitComponent.HandleState>(ent, DisposalUnitComponent.Visuals.Handle, out var handleState, appearance))
|
||||
handleState = DisposalUnitComponent.HandleState.Normal;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayEngaged, handleState != DisposalUnitComponent.HandleState.Normal);
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.OverlayEngaged, handleState != DisposalUnitComponent.HandleState.Normal);
|
||||
|
||||
if (!_appearanceSystem.TryGetData<DisposalUnitComponent.LightStates>(ent, DisposalUnitComponent.Visuals.Light, out var lightState, appearance))
|
||||
lightState = DisposalUnitComponent.LightStates.Off;
|
||||
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayCharging,
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.OverlayCharging,
|
||||
(lightState & DisposalUnitComponent.LightStates.Charging) != 0);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayReady,
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.OverlayReady,
|
||||
(lightState & DisposalUnitComponent.LightStates.Ready) != 0);
|
||||
sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayFull,
|
||||
_sprite.LayerSetVisible((ent, sprite), DisposalUnitVisualLayers.OverlayFull,
|
||||
(lightState & DisposalUnitComponent.LightStates.Full) != 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ public sealed class DoAfterOverlay : Overlay
|
|||
private readonly MetaDataSystem _meta;
|
||||
private readonly ProgressColorSystem _progressColor;
|
||||
private readonly SharedContainerSystem _container;
|
||||
private readonly SpriteSystem _sprite;
|
||||
|
||||
private readonly Texture _barTexture;
|
||||
private readonly ShaderInstance _unshadedShader;
|
||||
|
|
@ -45,6 +46,7 @@ public sealed class DoAfterOverlay : Overlay
|
|||
_meta = _entManager.EntitySysManager.GetEntitySystem<MetaDataSystem>();
|
||||
_container = _entManager.EntitySysManager.GetEntitySystem<SharedContainerSystem>();
|
||||
_progressColor = _entManager.System<ProgressColorSystem>();
|
||||
_sprite = _entManager.System<SpriteSystem>();
|
||||
var sprite = new SpriteSpecifier.Rsi(new("/Textures/Interface/Misc/progress_bar.rsi"), "icon");
|
||||
_barTexture = _entManager.EntitySysManager.GetEntitySystem<SpriteSystem>().Frame0(sprite);
|
||||
|
||||
|
|
@ -118,7 +120,7 @@ public sealed class DoAfterOverlay : Overlay
|
|||
|
||||
// Use the sprite itself if we know its bounds. This means short or tall sprites don't get overlapped
|
||||
// by the bar.
|
||||
float yOffset = sprite.Bounds.Height / 2f + 0.05f;
|
||||
var yOffset = _sprite.GetLocalBounds((uid, sprite)).Height / 2f + 0.05f;
|
||||
|
||||
// Position above the entity (we've already applied the matrix transform to the entity itself)
|
||||
// Offset by the texture size for every do_after we have.
|
||||
|
|
@ -135,7 +137,7 @@ public sealed class DoAfterOverlay : Overlay
|
|||
if (doAfter.CancelledTime != null)
|
||||
{
|
||||
var elapsed = doAfter.CancelledTime.Value - doAfter.StartTime;
|
||||
elapsedRatio = (float) Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
||||
elapsedRatio = (float)Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
||||
var cancelElapsed = (time - doAfter.CancelledTime.Value).TotalSeconds;
|
||||
var flash = Math.Floor(cancelElapsed / FlashTime) % 2 == 0;
|
||||
color = GetProgressColor(0, flash ? alpha : 0);
|
||||
|
|
@ -143,7 +145,7 @@ public sealed class DoAfterOverlay : Overlay
|
|||
else
|
||||
{
|
||||
var elapsed = time - doAfter.StartTime;
|
||||
elapsedRatio = (float) Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
||||
elapsedRatio = (float)Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
||||
color = GetProgressColor(elapsedRatio, alpha);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace Content.Client.Doors;
|
|||
public sealed class AirlockSystem : SharedAirlockSystem
|
||||
{
|
||||
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -21,7 +22,7 @@ public sealed class AirlockSystem : SharedAirlockSystem
|
|||
private void OnComponentStartup(EntityUid uid, AirlockComponent comp, ComponentStartup args)
|
||||
{
|
||||
// Has to be on component startup because we don't know what order components initialize in and running this before DoorComponent inits _will_ crash.
|
||||
if(!TryComp<DoorComponent>(uid, out var door))
|
||||
if (!TryComp<DoorComponent>(uid, out var door))
|
||||
return;
|
||||
|
||||
if (comp.OpenUnlitVisible) // Otherwise there are flashes of the fallback sprite between clicking on the door and the door closing animation starting.
|
||||
|
|
@ -57,19 +58,19 @@ public sealed class AirlockSystem : SharedAirlockSystem
|
|||
}
|
||||
};
|
||||
|
||||
if(!comp.AnimatePanel)
|
||||
if (!comp.AnimatePanel)
|
||||
return;
|
||||
|
||||
((Animation)door.OpeningAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick()
|
||||
{
|
||||
LayerKey = WiresVisualLayers.MaintenancePanel,
|
||||
KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningPanelSpriteState, 0f)},
|
||||
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningPanelSpriteState, 0f) },
|
||||
});
|
||||
|
||||
((Animation)door.ClosingAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick
|
||||
{
|
||||
LayerKey = WiresVisualLayers.MaintenancePanel,
|
||||
KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingPanelSpriteState, 0f)},
|
||||
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingPanelSpriteState, 0f) },
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -101,11 +102,12 @@ public sealed class AirlockSystem : SharedAirlockSystem
|
|||
&& !boltedVisible && !emergencyLightsVisible;
|
||||
}
|
||||
|
||||
args.Sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, unlitVisible);
|
||||
args.Sprite.LayerSetVisible(DoorVisualLayers.BaseBolted, boltedVisible);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), DoorVisualLayers.BaseUnlit, unlitVisible);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), DoorVisualLayers.BaseBolted, boltedVisible);
|
||||
if (comp.EmergencyAccessLayer)
|
||||
{
|
||||
args.Sprite.LayerSetVisible(
|
||||
_sprite.LayerSetVisible(
|
||||
(uid, args.Sprite),
|
||||
DoorVisualLayers.BaseEmergencyAccess,
|
||||
emergencyLightsVisible
|
||||
&& state != DoorState.Open
|
||||
|
|
@ -118,12 +120,12 @@ public sealed class AirlockSystem : SharedAirlockSystem
|
|||
switch (state)
|
||||
{
|
||||
case DoorState.Open:
|
||||
args.Sprite.LayerSetState(DoorVisualLayers.BaseUnlit, comp.ClosingSpriteState);
|
||||
args.Sprite.LayerSetAnimationTime(DoorVisualLayers.BaseUnlit, 0);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), DoorVisualLayers.BaseUnlit, comp.ClosingSpriteState);
|
||||
_sprite.LayerSetAnimationTime((uid, args.Sprite), DoorVisualLayers.BaseUnlit, 0);
|
||||
break;
|
||||
case DoorState.Closed:
|
||||
args.Sprite.LayerSetState(DoorVisualLayers.BaseUnlit, comp.OpeningSpriteState);
|
||||
args.Sprite.LayerSetAnimationTime(DoorVisualLayers.BaseUnlit, 0);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), DoorVisualLayers.BaseUnlit, comp.OpeningSpriteState);
|
||||
_sprite.LayerSetAnimationTime((uid, args.Sprite), DoorVisualLayers.BaseUnlit, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationSystem = default!;
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -85,7 +86,7 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
state = DoorState.Closed;
|
||||
|
||||
if (AppearanceSystem.TryGetData<string>(entity, DoorVisuals.BaseRSI, out var baseRsi, args.Component))
|
||||
UpdateSpriteLayers(args.Sprite, baseRsi);
|
||||
UpdateSpriteLayers((entity.Owner, args.Sprite), baseRsi);
|
||||
|
||||
if (_animationSystem.HasRunningAnimation(entity, DoorComponent.AnimationKey))
|
||||
_animationSystem.Stop(entity.Owner, DoorComponent.AnimationKey);
|
||||
|
|
@ -95,21 +96,21 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
|
||||
private void UpdateAppearanceForDoorState(Entity<DoorComponent> entity, SpriteComponent sprite, DoorState state)
|
||||
{
|
||||
sprite.DrawDepth = state is DoorState.Open ? entity.Comp.OpenDrawDepth : entity.Comp.ClosedDrawDepth;
|
||||
_sprite.SetDrawDepth((entity.Owner, sprite), state is DoorState.Open ? entity.Comp.OpenDrawDepth : entity.Comp.ClosedDrawDepth);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case DoorState.Open:
|
||||
foreach (var (layer, layerState) in entity.Comp.OpenSpriteStates)
|
||||
{
|
||||
sprite.LayerSetState(layer, layerState);
|
||||
_sprite.LayerSetRsiState((entity.Owner, sprite), layer, layerState);
|
||||
}
|
||||
|
||||
return;
|
||||
case DoorState.Closed:
|
||||
foreach (var (layer, layerState) in entity.Comp.ClosedSpriteStates)
|
||||
{
|
||||
sprite.LayerSetState(layer, layerState);
|
||||
_sprite.LayerSetRsiState((entity.Owner, sprite), layer, layerState);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -138,7 +139,7 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
}
|
||||
}
|
||||
|
||||
private void UpdateSpriteLayers(SpriteComponent sprite, string baseRsi)
|
||||
private void UpdateSpriteLayers(Entity<SpriteComponent> sprite, string baseRsi)
|
||||
{
|
||||
if (!_resourceCache.TryGetResource<RSIResource>(SpriteSpecifierSerializer.TextureRoot / baseRsi, out var res))
|
||||
{
|
||||
|
|
@ -146,6 +147,6 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
return;
|
||||
}
|
||||
|
||||
sprite.BaseRSI = res.RSI;
|
||||
_sprite.SetBaseRsi(sprite.AsNullable(), res.RSI);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ namespace Content.Client.Doors;
|
|||
public sealed class FirelockSystem : SharedFirelockSystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -18,7 +19,7 @@ public sealed class FirelockSystem : SharedFirelockSystem
|
|||
protected override void OnComponentStartup(Entity<FirelockComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
base.OnComponentStartup(ent, ref args);
|
||||
if(!TryComp<DoorComponent>(ent.Owner, out var door))
|
||||
if (!TryComp<DoorComponent>(ent.Owner, out var door))
|
||||
return;
|
||||
|
||||
door.ClosedSpriteStates.Add((DoorVisualLayers.BaseUnlit, ent.Comp.WarningLightSpriteState));
|
||||
|
|
@ -57,7 +58,7 @@ public sealed class FirelockSystem : SharedFirelockSystem
|
|||
|| state == DoorState.Denying
|
||||
|| (_appearanceSystem.TryGetData<bool>(uid, DoorVisuals.ClosedLights, out var closedLights, args.Component) && closedLights);
|
||||
|
||||
args.Sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, unlitVisible && !boltedVisible);
|
||||
args.Sprite.LayerSetVisible(DoorVisualLayers.BaseBolted, boltedVisible);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), DoorVisualLayers.BaseUnlit, unlitVisible && !boltedVisible);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), DoorVisualLayers.BaseBolted, boltedVisible);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ namespace Content.Client.Doors;
|
|||
public sealed class TurnstileSystem : SharedTurnstileSystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private static EntProtoId _examineArrow = "TurnstileArrow";
|
||||
private static readonly EntProtoId ExamineArrow = "TurnstileArrow";
|
||||
|
||||
private const string AnimationKey = "Turnstile";
|
||||
|
||||
|
|
@ -33,12 +34,12 @@ public sealed class TurnstileSystem : SharedTurnstileSystem
|
|||
|
||||
if (!TryComp<SpriteComponent>(ent, out var sprite))
|
||||
return;
|
||||
sprite.LayerSetState(TurnstileVisualLayers.Base, new RSI.StateId(ent.Comp.DefaultState));
|
||||
_sprite.LayerSetRsiState((ent.Owner, sprite), TurnstileVisualLayers.Base, new RSI.StateId(ent.Comp.DefaultState));
|
||||
}
|
||||
|
||||
private void OnExamined(Entity<TurnstileComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
Spawn(_examineArrow, new EntityCoordinates(ent, 0, 0));
|
||||
Spawn(ExamineArrow, new EntityCoordinates(ent, 0, 0));
|
||||
}
|
||||
|
||||
protected override void PlayAnimation(EntityUid uid, string stateId)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ namespace Content.Client.Dragon;
|
|||
public sealed class DragonSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedPointLightSystem _lights = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -31,7 +32,7 @@ public sealed class DragonSystem : EntitySystem
|
|||
switch (state.State)
|
||||
{
|
||||
case DragonRiftState.Charging:
|
||||
sprite?.LayerSetColor(0, Color.FromHex("#569fff"));
|
||||
_sprite.LayerSetColor((uid, sprite), 0, Color.FromHex("#569fff"));
|
||||
|
||||
if (light != null)
|
||||
{
|
||||
|
|
@ -39,7 +40,7 @@ public sealed class DragonSystem : EntitySystem
|
|||
}
|
||||
break;
|
||||
case DragonRiftState.AlmostFinished:
|
||||
sprite?.LayerSetColor(0, Color.FromHex("#cf4cff"));
|
||||
_sprite.LayerSetColor((uid, sprite), 0, Color.FromHex("#cf4cff"));
|
||||
|
||||
if (light != null)
|
||||
{
|
||||
|
|
@ -47,7 +48,7 @@ public sealed class DragonSystem : EntitySystem
|
|||
}
|
||||
break;
|
||||
case DragonRiftState.Finished:
|
||||
sprite?.LayerSetColor(0, Color.FromHex("#edbc36"));
|
||||
_sprite.LayerSetColor((uid, sprite), 0, Color.FromHex("#edbc36"));
|
||||
|
||||
if (light != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using Content.Shared.Drugs;
|
|||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Client.Drugs;
|
||||
|
||||
|
|
@ -12,6 +13,7 @@ public sealed class DrugOverlaySystem : EntitySystem
|
|||
{
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlayMan = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
private RainbowOverlay _overlay = default!;
|
||||
|
||||
|
|
@ -45,8 +47,11 @@ public sealed class DrugOverlaySystem : EntitySystem
|
|||
private void OnInit(EntityUid uid, SeeingRainbowsComponent component, ComponentInit args)
|
||||
{
|
||||
if (_player.LocalEntity == uid)
|
||||
{
|
||||
_overlay.Phase = _random.NextFloat(MathF.Tau); // random starting phase for movement effect
|
||||
_overlayMan.AddOverlay(_overlay);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnShutdown(EntityUid uid, SeeingRainbowsComponent component, ComponentShutdown args)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,16 +24,27 @@ public sealed class RainbowOverlay : Overlay
|
|||
|
||||
public float Intoxication = 0.0f;
|
||||
public float TimeTicker = 0.0f;
|
||||
public float Phase = 0.0f;
|
||||
|
||||
private const float VisualThreshold = 10.0f;
|
||||
private const float PowerDivisor = 250.0f;
|
||||
private float _timeScale = 0.0f;
|
||||
private float _warpScale = 0.0f;
|
||||
|
||||
private float EffectScale => Math.Clamp((Intoxication - VisualThreshold) / PowerDivisor, 0.0f, 1.0f);
|
||||
|
||||
public RainbowOverlay()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_rainbowShader = _prototypeManager.Index<ShaderPrototype>("Rainbow").InstanceUnique();
|
||||
_config.OnValueChanged(CCVars.ReducedMotion, OnReducedMotionChanged, invokeImmediately: true);
|
||||
}
|
||||
|
||||
private void OnReducedMotionChanged(bool reducedMotion)
|
||||
{
|
||||
_timeScale = reducedMotion ? 0.0f : 1.0f;
|
||||
_warpScale = reducedMotion ? 0.0f : 1.0f;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
|
|
@ -51,7 +62,7 @@ public sealed class RainbowOverlay : Overlay
|
|||
if (!statusSys.TryGetTime(playerEntity.Value, DrugOverlaySystem.RainbowKey, out var time, status))
|
||||
return;
|
||||
|
||||
var timeLeft = (float) (time.Value.Item2 - time.Value.Item1).TotalSeconds;
|
||||
var timeLeft = (float)(time.Value.Item2 - time.Value.Item1).TotalSeconds;
|
||||
|
||||
TimeTicker += args.DeltaSeconds;
|
||||
|
||||
|
|
@ -61,7 +72,7 @@ public sealed class RainbowOverlay : Overlay
|
|||
}
|
||||
else
|
||||
{
|
||||
Intoxication -= Intoxication/(timeLeft - TimeTicker) * args.DeltaSeconds;
|
||||
Intoxication -= Intoxication / (timeLeft - TimeTicker) * args.DeltaSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,16 +89,15 @@ public sealed class RainbowOverlay : Overlay
|
|||
|
||||
protected override void Draw(in OverlayDrawArgs args)
|
||||
{
|
||||
// TODO disable only the motion part or ike's idea (single static frame of the overlay)
|
||||
if (_config.GetCVar(CCVars.ReducedMotion))
|
||||
return;
|
||||
|
||||
if (ScreenTexture == null)
|
||||
return;
|
||||
|
||||
var handle = args.WorldHandle;
|
||||
_rainbowShader.SetParameter("SCREEN_TEXTURE", ScreenTexture);
|
||||
_rainbowShader.SetParameter("effectScale", EffectScale);
|
||||
_rainbowShader.SetParameter("colorScale", EffectScale);
|
||||
_rainbowShader.SetParameter("timeScale", _timeScale);
|
||||
_rainbowShader.SetParameter("warpScale", _warpScale * EffectScale);
|
||||
_rainbowShader.SetParameter("phase", Phase);
|
||||
handle.UseShader(_rainbowShader);
|
||||
handle.DrawRect(args.WorldBounds, Color.White);
|
||||
handle.UseShader(null);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public sealed class ColorFlashEffectSystem : SharedColorFlashEffectSystem
|
|||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly AnimationPlayerSystem _animation = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <summary>
|
||||
/// It's a little on the long side but given we use multiple colours denoting what happened it makes it easier to register.
|
||||
|
|
@ -44,7 +45,7 @@ public sealed class ColorFlashEffectSystem : SharedColorFlashEffectSystem
|
|||
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite))
|
||||
{
|
||||
sprite.Color = component.Color;
|
||||
_sprite.SetColor((uid, sprite), component.Color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,15 +53,12 @@ public sealed class ElectrocutionHUDVisualizerSystem : VisualizerSystem<Electroc
|
|||
private void ShowHUD()
|
||||
{
|
||||
var electrifiedQuery = AllEntityQuery<ElectrocutionHUDVisualsComponent, AppearanceComponent, SpriteComponent>();
|
||||
while (electrifiedQuery.MoveNext(out var uid, out var _, out var appearanceComp, out var spriteComp))
|
||||
while (electrifiedQuery.MoveNext(out var uid, out _, out var appearanceComp, out var spriteComp))
|
||||
{
|
||||
if (!AppearanceSystem.TryGetData<bool>(uid, ElectrifiedVisuals.IsElectrified, out var electrified, appearanceComp))
|
||||
continue;
|
||||
|
||||
if (electrified)
|
||||
spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, true);
|
||||
else
|
||||
spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, false);
|
||||
SpriteSystem.LayerSetVisible((uid, spriteComp), ElectrifiedLayers.HUD, electrified);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,10 +67,9 @@ public sealed class ElectrocutionHUDVisualizerSystem : VisualizerSystem<Electroc
|
|||
private void RemoveHUD()
|
||||
{
|
||||
var electrifiedQuery = AllEntityQuery<ElectrocutionHUDVisualsComponent, AppearanceComponent, SpriteComponent>();
|
||||
while (electrifiedQuery.MoveNext(out var uid, out var _, out var appearanceComp, out var spriteComp))
|
||||
while (electrifiedQuery.MoveNext(out var uid, out _, out _, out var spriteComp))
|
||||
{
|
||||
|
||||
spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, false);
|
||||
SpriteSystem.LayerSetVisible((uid, spriteComp), ElectrifiedLayers.HUD, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,9 +83,6 @@ public sealed class ElectrocutionHUDVisualizerSystem : VisualizerSystem<Electroc
|
|||
return;
|
||||
|
||||
var player = _playerMan.LocalEntity;
|
||||
if (electrified && HasComp<ShowElectrocutionHUDComponent>(player))
|
||||
args.Sprite.LayerSetVisible(ElectrifiedLayers.HUD, true);
|
||||
else
|
||||
args.Sprite.LayerSetVisible(ElectrifiedLayers.HUD, false);
|
||||
SpriteSystem.LayerSetVisible((uid, args.Sprite), ElectrifiedLayers.HUD, electrified && HasComp<ShowElectrocutionHUDComponent>(player));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
using Content.Shared.Ensnaring;
|
||||
using Content.Shared.Ensnaring.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Ensnaring;
|
||||
|
||||
public sealed class EnsnareableSystem : SharedEnsnareableSystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -19,25 +21,25 @@ public sealed class EnsnareableSystem : SharedEnsnareableSystem
|
|||
{
|
||||
base.OnEnsnareInit(ent, ref args);
|
||||
|
||||
if(!TryComp<SpriteComponent>(ent.Owner, out var sprite))
|
||||
if (!TryComp<SpriteComponent>(ent.Owner, out var sprite))
|
||||
return;
|
||||
|
||||
// TODO remove this, this should just be in yaml.
|
||||
sprite.LayerMapReserveBlank(EnsnaredVisualLayers.Ensnared);
|
||||
_sprite.LayerMapReserve((ent.Owner, sprite), EnsnaredVisualLayers.Ensnared);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(EntityUid uid, EnsnareableComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null || !args.Sprite.LayerMapTryGet(EnsnaredVisualLayers.Ensnared, out var layer))
|
||||
if (args.Sprite == null || !_sprite.LayerMapTryGet((uid, args.Sprite), EnsnaredVisualLayers.Ensnared, out var layer, false))
|
||||
return;
|
||||
|
||||
if (_appearance.TryGetData<bool>(uid, EnsnareableVisuals.IsEnsnared, out var isEnsnared, args.Component))
|
||||
{
|
||||
if (component.Sprite != null)
|
||||
{
|
||||
args.Sprite.LayerSetRSI(layer, component.Sprite);
|
||||
args.Sprite.LayerSetState(layer, component.State);
|
||||
args.Sprite.LayerSetVisible(layer, isEnsnared);
|
||||
_sprite.LayerSetRsi((uid, args.Sprite), layer, new ResPath(component.Sprite));
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, component.State);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, isEnsnared);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,6 @@ public sealed class ClusterGrenadeVisualizerSystem : VisualizerSystem<ClusterGre
|
|||
return;
|
||||
|
||||
if (AppearanceSystem.TryGetData<int>(uid, ClusterGrenadeVisuals.GrenadesCounter, out var grenadesCounter, args.Component))
|
||||
args.Sprite.LayerSetState(0, $"{comp.State}-{grenadesCounter}");
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), 0, $"{comp.State}-{grenadesCounter}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using Robust.Client.Graphics;
|
|||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Explosion;
|
||||
|
|
@ -19,7 +18,7 @@ public sealed class ExplosionOverlaySystem : EntitySystem
|
|||
[Dependency] private readonly IResourceCache _resCache = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlayMan = default!;
|
||||
[Dependency] private readonly SharedPointLightSystem _lights = default!;
|
||||
[Dependency] private readonly IMapManager _mapMan = default!;
|
||||
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
|
||||
public override void Initialize()
|
||||
|
|
@ -69,7 +68,7 @@ public sealed class ExplosionOverlaySystem : EntitySystem
|
|||
}
|
||||
|
||||
// Map may have been deleted.
|
||||
if (_mapMan.MapExists(component.Epicenter.MapId))
|
||||
if (_mapSystem.MapExists(component.Epicenter.MapId))
|
||||
{
|
||||
// spawn in a client-side light source at the epicenter
|
||||
var lightEntity = Spawn("ExplosionLight", component.Epicenter);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ public sealed partial class TriggerSystem
|
|||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _player = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/*
|
||||
* Currently all of the appearance stuff is hardcoded for portable flashers
|
||||
|
|
@ -79,7 +80,7 @@ public sealed partial class TriggerSystem
|
|||
if (!_appearance.TryGetData<ProximityTriggerVisuals>(uid, ProximityTriggerVisualState.State, out var state, appearance))
|
||||
return;
|
||||
|
||||
if (!spriteComponent.LayerMapTryGet(ProximityTriggerVisualLayers.Base, out var layer))
|
||||
if (!_sprite.LayerMapTryGet((uid, spriteComponent), ProximityTriggerVisualLayers.Base, out var layer, false))
|
||||
// Don't do anything if the sprite doesn't have the layer.
|
||||
return;
|
||||
|
||||
|
|
@ -89,7 +90,7 @@ public sealed partial class TriggerSystem
|
|||
// Don't interrupt the flash animation
|
||||
if (_player.HasRunningAnimation(uid, player, AnimKey)) return;
|
||||
_player.Stop(uid, player, AnimKey);
|
||||
spriteComponent.LayerSetState(layer, "on");
|
||||
_sprite.LayerSetRsiState((uid, spriteComponent), layer, "on");
|
||||
break;
|
||||
case ProximityTriggerVisuals.Active:
|
||||
if (_player.HasRunningAnimation(uid, player, AnimKey)) return;
|
||||
|
|
@ -98,7 +99,7 @@ public sealed partial class TriggerSystem
|
|||
case ProximityTriggerVisuals.Off:
|
||||
default:
|
||||
_player.Stop(uid, player, AnimKey);
|
||||
spriteComponent.LayerSetState(layer, "off");
|
||||
_sprite.LayerSetRsiState((uid, spriteComponent), layer, "off");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,45 +1,119 @@
|
|||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
<DefaultWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
Title="{Loc 'fax-machine-ui-window'}"
|
||||
MinWidth="250">
|
||||
<BoxContainer Orientation="Vertical" VerticalExpand="True">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Label Text="{Loc 'fax-machine-ui-paper'}" />
|
||||
<Control MinWidth="4" />
|
||||
<Label Name="PaperStatusLabel" />
|
||||
MinSize="380 220">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
SeparationOverride="2"
|
||||
VerticalExpand="True">
|
||||
|
||||
<PanelContainer StyleClasses="PanelBackgroundBaseDark" HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
Margin="0 0 0 2">
|
||||
|
||||
<!-- From Line -->
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
|
||||
<!-- From Value Name -->
|
||||
<Label Text="{Loc 'fax-machine-ui-from'}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom"/>
|
||||
|
||||
<Control HorizontalExpand="True"
|
||||
MinWidth="8"
|
||||
HorizontalAlignment="Center"/>
|
||||
|
||||
<!-- From Value -->
|
||||
<Label Name="FromLabel"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Align="Right"/>
|
||||
</BoxContainer>
|
||||
<Control HorizontalExpand="True" MinHeight="20" />
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Label Text="{Loc 'fax-machine-ui-from'}" />
|
||||
<Control MinWidth="4" />
|
||||
<Label Name="FromLabel" />
|
||||
|
||||
<!-- To Line -->
|
||||
<BoxContainer
|
||||
Orientation="Horizontal">
|
||||
|
||||
<!-- To Label -->
|
||||
<Label Text="{Loc 'fax-machine-ui-to'}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom"/>
|
||||
|
||||
<Control HorizontalExpand="True"
|
||||
MinWidth="8"
|
||||
HorizontalAlignment="Center"/>
|
||||
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<!-- To Value -->
|
||||
<OptionButton Name="PeerSelector"
|
||||
StyleClasses="OpenRight" />
|
||||
|
||||
<!-- Refresh Fax Recipients -->
|
||||
<Button StyleClasses="OpenLeft"
|
||||
Name="RefreshButton"
|
||||
ToolTip="{Loc 'fax-machine-ui-refresh-button'}">
|
||||
<TextureButton
|
||||
MouseFilter="Ignore"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Scale="0.9 0.9"
|
||||
StyleClasses="Refresh" />
|
||||
</Button>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Label Text="{Loc 'fax-machine-ui-to'}" />
|
||||
<Control MinWidth="4" />
|
||||
<OptionButton Name="PeerSelector" HorizontalExpand="True" />
|
||||
</BoxContainer>
|
||||
<Control HorizontalExpand="True" MinHeight="20" />
|
||||
|
||||
<PanelContainer StyleClasses="LowDivider" Margin="0 4 0 4"/>
|
||||
|
||||
<!-- Send & Copy -->
|
||||
<BoxContainer Orientation="Vertical">
|
||||
|
||||
<!-- Paper Status -->
|
||||
<Label Name="PaperStatusLabel"
|
||||
HorizontalAlignment="Center" />
|
||||
|
||||
<BoxContainer>
|
||||
<!--> Sunrise-Edit <-->
|
||||
<!--> <BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<Button Name="FileButton"
|
||||
Text="{Loc 'fax-machine-ui-file-button'}"
|
||||
HorizontalExpand="False"/>
|
||||
</BoxContainer> <-->
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<!--> Sunrise-Edit <-->
|
||||
<!--> <Button Name="CopyButton"
|
||||
<!--><Button Name="CopyButton"
|
||||
Text="{Loc 'fax-machine-ui-copy-button'}"
|
||||
HorizontalExpand="False"
|
||||
Disabled="True" /> <-->
|
||||
StyleClasses="OpenRight"
|
||||
HorizontalExpand="True"
|
||||
Disabled="True" /><-->
|
||||
<Button Name="SendButton"
|
||||
Text="{Loc 'fax-machine-ui-send-button'}"
|
||||
StyleClasses="OpenLeft"
|
||||
HorizontalExpand="True"
|
||||
Disabled="True" />
|
||||
<Button Name="RefreshButton"
|
||||
Text="{Loc 'fax-machine-ui-refresh-button'}" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
</PanelContainer>
|
||||
|
||||
<PanelContainer StyleClasses="PanelBackgroundBaseDark"
|
||||
HorizontalExpand="True" Margin="0 10 0 0"
|
||||
VerticalExpand="True" VerticalAlignment="Bottom">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
VerticalExpand="True">
|
||||
|
||||
<!-- Other actions -->
|
||||
<BoxContainer Margin="0 4 0 4">
|
||||
|
||||
<Button Name="PaperButton"
|
||||
Text="{Loc 'fax-machine-ui-paper-button-normal'}"
|
||||
HorizontalExpand="False"/>
|
||||
StyleClasses="OpenRight"
|
||||
HorizontalExpand="True"/>
|
||||
|
||||
<!--> Sunrise-Edit <-->
|
||||
<!--><Button Name="FileButton"
|
||||
Text="{Loc 'fax-machine-ui-file-button'}"
|
||||
StyleClasses="OpenLeft"
|
||||
HorizontalExpand="True"/>
|
||||
<-->
|
||||
|
||||
</BoxContainer>
|
||||
|
||||
<!-- It would be cool to add a display of the inserted file here. -->
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace Content.Client.Fluids;
|
|||
public sealed class PuddleSystem : SharedPuddleSystem
|
||||
{
|
||||
[Dependency] private readonly IconSmoothSystem _smooth = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -27,7 +28,7 @@ public sealed class PuddleSystem : SharedPuddleSystem
|
|||
|
||||
if (args.AppearanceData.TryGetValue(PuddleVisuals.CurrentVolume, out var volumeObj))
|
||||
{
|
||||
volume = (float) volumeObj;
|
||||
volume = (float)volumeObj;
|
||||
}
|
||||
|
||||
// Update smoothing and sprite based on volume.
|
||||
|
|
@ -35,19 +36,19 @@ public sealed class PuddleSystem : SharedPuddleSystem
|
|||
{
|
||||
if (volume < LowThreshold)
|
||||
{
|
||||
args.Sprite.LayerSetState(0, $"{smooth.StateBase}a");
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), 0, $"{smooth.StateBase}a");
|
||||
_smooth.SetEnabled(uid, false, smooth);
|
||||
}
|
||||
else if (volume < MediumThreshold)
|
||||
{
|
||||
args.Sprite.LayerSetState(0, $"{smooth.StateBase}b");
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), 0, $"{smooth.StateBase}b");
|
||||
_smooth.SetEnabled(uid, false, smooth);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!smooth.Enabled)
|
||||
{
|
||||
args.Sprite.LayerSetState(0, $"{smooth.StateBase}0");
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), 0, $"{smooth.StateBase}0");
|
||||
_smooth.SetEnabled(uid, true, smooth);
|
||||
_smooth.DirtyNeighbours(uid);
|
||||
}
|
||||
|
|
@ -58,12 +59,12 @@ public sealed class PuddleSystem : SharedPuddleSystem
|
|||
|
||||
if (args.AppearanceData.TryGetValue(PuddleVisuals.SolutionColor, out var colorObj))
|
||||
{
|
||||
var color = (Color) colorObj;
|
||||
args.Sprite.Color = color * baseColor;
|
||||
var color = (Color)colorObj;
|
||||
_sprite.SetColor((uid, args.Sprite), color * baseColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Sprite.Color *= baseColor;
|
||||
_sprite.SetColor((uid, args.Sprite), args.Sprite.Color * baseColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace Content.Client.Ghost
|
|||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
[Dependency] private readonly PointLightSystem _pointLightSystem = default!;
|
||||
[Dependency] private readonly ContentEyeSystem _contentEye = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly AudioSystem _audioSystem = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!; // Sunrise-Edit
|
||||
|
||||
|
|
@ -41,7 +42,7 @@ namespace Content.Client.Ghost
|
|||
var query = AllEntityQuery<GhostComponent, SpriteComponent>();
|
||||
while (query.MoveNext(out var uid, out _, out var sprite))
|
||||
{
|
||||
sprite.Visible = value || uid == _playerManager.LocalEntity;
|
||||
_sprite.SetVisible((uid, sprite), value || uid == _playerManager.LocalEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -78,7 +79,7 @@ namespace Content.Client.Ghost
|
|||
private void OnStartup(EntityUid uid, GhostComponent component, ComponentStartup args)
|
||||
{
|
||||
if (TryComp(uid, out SpriteComponent? sprite))
|
||||
sprite.Visible = GhostVisibility || uid == _playerManager.LocalEntity;
|
||||
_sprite.SetVisible((uid, sprite), GhostVisibility || uid == _playerManager.LocalEntity);
|
||||
}
|
||||
|
||||
private void OnToggleLighting(EntityUid uid, EyeComponent component, ToggleLightingActionEvent args)
|
||||
|
|
@ -156,7 +157,7 @@ namespace Content.Client.Ghost
|
|||
private void OnGhostState(EntityUid uid, GhostComponent component, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite))
|
||||
sprite.LayerSetColor(0, component.Color);
|
||||
_sprite.LayerSetColor((uid, sprite), 0, component.Color);
|
||||
|
||||
if (uid != _playerManager.LocalEntity)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public sealed class GhostToggleSelfVisibility : IConsoleCommand
|
|||
if (!entityManager.TryGetComponent(attachedEntity, out SpriteComponent? spriteComponent))
|
||||
return;
|
||||
|
||||
spriteComponent.Visible = !spriteComponent.Visible;
|
||||
var spriteSys = entityManager.System<SpriteSystem>();
|
||||
spriteSys.SetVisible((attachedEntity.Value, spriteComponent), !spriteComponent.Visible);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ namespace Content.Client.Gravity;
|
|||
public sealed partial class GravitySystem : SharedGravitySystem
|
||||
{
|
||||
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
|
@ -26,34 +28,34 @@ public sealed partial class GravitySystem : SharedGravitySystem
|
|||
{
|
||||
if (comp.SpriteMap.TryGetValue(state, out var spriteState))
|
||||
{
|
||||
var layer = args.Sprite.LayerMapGet(GravityGeneratorVisualLayers.Base);
|
||||
args.Sprite.LayerSetState(layer, spriteState);
|
||||
var layer = _sprite.LayerMapGet((uid, args.Sprite), GravityGeneratorVisualLayers.Base);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, spriteState);
|
||||
}
|
||||
}
|
||||
|
||||
if (_appearanceSystem.TryGetData<float>(uid, PowerChargeVisuals.Charge, out var charge, args.Component))
|
||||
{
|
||||
var layer = args.Sprite.LayerMapGet(GravityGeneratorVisualLayers.Core);
|
||||
var layer = _sprite.LayerMapGet((uid, args.Sprite), GravityGeneratorVisualLayers.Core);
|
||||
switch (charge)
|
||||
{
|
||||
case < 0.2f:
|
||||
args.Sprite.LayerSetVisible(layer, false);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, false);
|
||||
break;
|
||||
case >= 0.2f and < 0.4f:
|
||||
args.Sprite.LayerSetVisible(layer, true);
|
||||
args.Sprite.LayerSetState(layer, comp.CoreStartupState);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, true);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, comp.CoreStartupState);
|
||||
break;
|
||||
case >= 0.4f and < 0.6f:
|
||||
args.Sprite.LayerSetVisible(layer, true);
|
||||
args.Sprite.LayerSetState(layer, comp.CoreIdleState);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, true);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, comp.CoreIdleState);
|
||||
break;
|
||||
case >= 0.6f and < 0.8f:
|
||||
args.Sprite.LayerSetVisible(layer, true);
|
||||
args.Sprite.LayerSetState(layer, comp.CoreActivatingState);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, true);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, comp.CoreActivatingState);
|
||||
break;
|
||||
default:
|
||||
args.Sprite.LayerSetVisible(layer, true);
|
||||
args.Sprite.LayerSetState(layer, comp.CoreActivatedState);
|
||||
_sprite.LayerSetVisible((uid, args.Sprite), layer, true);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), layer, comp.CoreActivatedState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,12 +28,15 @@ public sealed partial class GuideEntityEmbed : BoxContainer, IDocumentTag
|
|||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IEntitySystemManager _systemManager = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
[Dependency] private readonly IUserInterfaceManager _ui = default!;
|
||||
|
||||
private readonly TagSystem _tagSystem;
|
||||
private readonly ExamineSystem _examineSystem;
|
||||
private readonly GuidebookSystem _guidebookSystem;
|
||||
|
||||
private readonly ISawmill _sawmill;
|
||||
|
||||
public bool Interactive;
|
||||
|
||||
public Entity<SpriteComponent>? Sprite => View.Entity == null || View.Sprite == null
|
||||
|
|
@ -53,6 +56,7 @@ public sealed partial class GuideEntityEmbed : BoxContainer, IDocumentTag
|
|||
_tagSystem = _systemManager.GetEntitySystem<TagSystem>();
|
||||
_examineSystem = _systemManager.GetEntitySystem<ExamineSystem>();
|
||||
_guidebookSystem = _systemManager.GetEntitySystem<GuidebookSystem>();
|
||||
_sawmill = _logManager.GetSawmill("guidebook.entity");
|
||||
MouseFilter = MouseFilterMode.Stop;
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +139,7 @@ public sealed partial class GuideEntityEmbed : BoxContainer, IDocumentTag
|
|||
{
|
||||
if (!args.TryGetValue("Entity", out var proto))
|
||||
{
|
||||
Logger.Error("Entity embed tag is missing entity prototype argument");
|
||||
_sawmill.Error("Entity embed tag is missing entity prototype argument");
|
||||
control = null;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue