Compare commits

...

704 Commits

Author SHA1 Message Date
Ed
592a3f4571 add magic sprites 2024-05-13 22:43:27 +03:00
Ed
27f031f466 setup ambience rule 2024-05-09 14:03:49 +03:00
Ed
cda201720b Update audio.yml 2024-05-09 01:17:49 +03:00
Ed
50c4fd3a58 Content stitching (#147)
* upgrade loadouts and gamemode

* fixes

* fix lobby images, add localization to loadouts

* fix clothing layers

* fix checks

* Update base.yml

* Update base.yml

* fuckthis, secret weights
2024-05-08 22:41:34 +03:00
Agoichi
b74d1b62b5 Adding attributes (#146)
* Delete Resources/Audio/_CP14/Effects/crystal_shatter.ogg

* Create attributions.yml

* Update attributions.yml

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
2024-05-08 17:27:28 +03:00
Ed
7b2328ba22 Alchemy tools: pestle and mortar (#144)
* add mortar & pestle mechanic

* setup prototypes

* Update mixing_types.yml

* add bubble sound collection, fix errors
2024-05-08 17:15:31 +03:00
Litogin
54d86b8d8f whitelist alchemy furnace (#143) 2024-05-08 12:41:18 +03:00
Ed
27047a3a37 Merge pull request #145 from crystallpunk-14/ed-08-05-2024-upstream
Ed 08 05 2024 upstream
2024-05-08 12:38:08 +03:00
Ed
b92032fdd7 Merge remote-tracking branch 'refs/remotes/upstream/master' into ed-08-05-2024-upstream
# Conflicts:
#	Content.Server/GameTicking/GameTicker.Spawning.cs
#	Content.Shared/Preferences/HumanoidCharacterProfile.cs
#	Resources/Prototypes/lobbyscreens.yml
2024-05-08 12:26:05 +03:00
Tornado Tech
31491775e5 Added new HTN operations and preconditions (#27486)
* Added new HTN operations & preconditions

* Ok I forgot about partial

* Namespace pierce the skies

* Some fixes, debug and new operators

* Bruh git eat my files
2024-05-08 12:18:03 +03:00
Ed
9fe1528490 Update eldermourne.ogg 2024-05-08 12:10:05 +03:00
Ed
6102d3c63d +1 song 2024-05-08 12:07:41 +03:00
PJBot
29860a0cf7 Automatic changelog update 2024-05-08 07:31:59 +00:00
Hobbitmax
aad5b9e53b Replace Train syndicate Jaws (#27734)
Should push the right changes to my Train Branch
2024-05-08 10:30:53 +03:00
Plykiya
1952ae3267 Reimplement supplybots as non-vehicles (#27769)
* Reimplement supplybots as non-vehicles

* what the hell is a container container?

* Dumpable

* let them hear supply comms

* unmigrate

* no more QM access

* Skill issue

---------

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-05-08 10:30:03 +03:00
Kukutis96513
dd51d0e19e Secoff senior uniform fix (#27775)
* weh.

* get the weh out of my repository

* add best lizard figurine

* remove umbra stuff from master

* remove the additional pixels from the senior secoff jumpskirt sprite

* fix the fix
2024-05-08 08:57:21 +02:00
PJBot
c097c98a1e Automatic changelog update 2024-05-08 06:50:34 +00:00
ShadowCommander
83099640e6 Fix pull not stopping when character is downed (#27796) 2024-05-08 08:49:28 +02:00
PJBot
1a09374b01 Automatic changelog update 2024-05-08 06:47:10 +00:00
Verm
99212762d6 Fix cak and breaddog not being able to escape inventories (#27794)
Fix cak and breaddog
2024-05-08 08:46:48 +02:00
Cojoke
b104125c0e Shoot Over Racks (#27797)
Racks now have table collisions
2024-05-08 08:46:03 +02:00
DrSmugleaf
15153d95a4 Fix the changelog window being very laggy until a tab is clicked (#27795) 2024-05-07 23:23:26 -07:00
Flareguy
caa822b9a0 Revert "Make the floppy lizard ears have two colors." (#27790)
Revert "Make the floppy lizard ears have two colors. (#27679)"

This reverts commit bd06aa2365.
2024-05-07 20:48:42 -07:00
Pieter-Jan Briers
9efe4dc701 Fix preferences sent to client not being sanitized (#27789)
Fucking whoops

In #27742 I made it so sanitization of character profiles was moved to be *after* database load. Except that means I moved it to be after the copy of all character profiles got sent to the client.

Move the sending to *also* be in that second load stage, and rename it. Fixes the issue.
2024-05-08 04:24:54 +02:00
PJBot
ab1a2de367 Automatic changelog update 2024-05-08 00:26:47 +00:00
deltanedas
d6d1c9ed8a make dragons breathe fire (#26746)
* add ActionGun system

* add RepeatingTrigger

* dragons breath projectile, repeatedly explodes

* give dragon fire breathing action, fireproof it

* oop

* oop 2

* prevent troll

* proper repeating thing

* pro

* webedit ops

* realops

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-05-07 17:25:41 -07:00
pigeonpeas
bd06aa2365 Make the floppy lizard ears have two colors. (#27679)
* Make the floppy lizard ears have two colors.

* please fix whatever the hell happened

* fix the error

* suggestion from Ubaser

* another suggestion from ubaser
2024-05-07 17:22:25 -07:00
PJBot
18bd221407 Automatic changelog update 2024-05-08 00:21:01 +00:00
OnsenCapy
8ec52ff69c Change combat gloves sprite (#27373)
* Changed combat gloves sprite.

* Edited combat gloves sprite.
2024-05-07 17:19:55 -07:00
deltanedas
89cbb100fd make hyper printer inherit base lathe (#27777)
Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-05-07 16:42:28 -04:00
TurboTracker
24e227660a Stop Toilets crushing you into walls (#27778) 2024-05-07 21:44:20 +02:00
PJBot
685188fd10 Automatic changelog update 2024-05-07 18:21:50 +00:00
deltanedas
262b9698cf make lube speed up lathes (#25515)
* add LatheGetSpeedEvent

* add LatheLube system

* make typical lathes accept lube

* spill

* :trollface:

* rework to generic ReagentSpeedSystem

* hyperlathe ops

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-05-07 14:20:43 -04:00
PJBot
6301e94390 Automatic changelog update 2024-05-07 18:16:04 +00:00
Hannah Giovanna Dawson
b90373356e Weapon Reflection Movement Mechanic (#27219)
* Weapon Reflection Movement Mechanic

Adds a movement mechanic to deflection.
Standing still gives you your best chance of deflecting a shot.
Moving lowers this to 2/3rds. Sprinting to 1/3rd.

This allows for robust players to express better and provides
counterplay to someone finding a goober-strong deflection
weapon, giving more design space.

As part of this PR I've also touched the numbers of a few swords,
shields, etc. and modified some descriptions to make them read
better. The balance numbers are not remotely final, but as intent:

1. All the sidearm swords (katana, cutlass, captain's sabre) have the same damage. There's no good reason the "ceremonial" blade the captain has doing more damage than a katana.
2. The Captain's Sabre has a 30% reflect chance, dropping to 20% when moving and 10% when sprinting. This one is controversial due to the recent nerf, I suspect: This could easily be 15->10->5?
3. The Energy Katana has a flat 30% reflect chance.
4. The meme Throngler has a 30% reflect chance, dropping to 20% when moving and 10% when sprinting.
5. The E-Sword has a 30% reflect chance, dropping to 20% when moving and 10% when sprinting.
6. The Double E-Sword has a mighty 75% reflect chance, dropping to 50% and then 25%.
7. Both reflective shields - Mirror and Energy - have a 95% deflect chance, dropping to 63% then 31%.

* Resolve PR comments.

* Weh?

* Reign in double esword a tad

* Shield nerfs no longer real

* Improve Mirror Cult desc

* Simple alert for deflection! No art yet.

* Added a new icon for deflecting
2024-05-07 20:14:58 +02:00
PJBot
cd8e90c58e Automatic changelog update 2024-05-07 15:56:09 +00:00
cool dolphin
64548a7ead More trinkets for loadouts (#27292)
* woo yea more tinket

* plushie has no timer
2024-05-07 17:55:03 +02:00
ShadowCommander
0926891f4f Set max line width to 120 (#27765) 2024-05-07 17:33:00 +02:00
PJBot
31a8327106 Automatic changelog update 2024-05-07 15:14:35 +00:00
Kara
09b5319270 Log event starts to admin alert chat (#27761) 2024-05-07 17:13:28 +02:00
Łukasz Mędrek
28f5d490a4 Fix construction instructions on flippables (#27574)
Fixes #27547
2024-05-07 20:53:59 +10:00
metalgearsloth
1e30234539 Revert "Fix turned off thrusters consume power" (#27755)
Revert "Fix turned off thrusters consume power (#26690)"

This reverts commit 70959e7bb0.
2024-05-07 20:52:18 +10:00
ShadowCommander
b9906eb34c Make arguments and parameters wrap to one variable per line (#27766) 2024-05-07 20:50:22 +10:00
PJBot
35dc85fd47 Automatic changelog update 2024-05-07 07:27:38 +00:00
lzk
d099b63424 Little morgue overhaul (#27750) 2024-05-07 10:26:33 +03:00
PJBot
0cb50a24c3 Automatic changelog update 2024-05-07 04:22:10 +00:00
Pieter-Jan Briers
7a38b22ddb Fix preference loading bugs (#27742)
First bug: if an error occured during pref loading code, it would fail. If the person then readied up, it would likely cause the round to fail to start.

Why could they ready up? The code only checks that the prefs finished loading, not that they finished loading *successfully*. Whoops.

Anyways, now people get kicked if their prefs fail to load. And I improved the error handling.

Second bug: if a user disconnected while their prefs were loading, it would cause an exception. This exception would go unobserved on lobby servers or raise through gameticker on non-lobby servers.

This happened even on a live server once and then triggered the first bug, but idk how.

Fixed this by properly plumbing through cancellation into the preferences loading code. The stuff is now cancelled properly.

Third bug: if somebody has a loadout item with a playtime requirement active, load-time sanitization of player prefs could run into a race condition because the sanitization can happen *before* play time was loaded.

Fixed by moving pref sanitizations to a later stage in the load process.
2024-05-07 14:21:03 +10:00
PJBot
61c1aeddf3 Automatic changelog update 2024-05-07 03:25:14 +00:00
Kara
7d7c71e6a6 Reduce ratking chance severely (#27760) 2024-05-06 23:23:50 -04:00
Flareguy
e4a516514f Adds most non-displacement-mappable vox sprites (#27577)
* non-displacement-mappable vox sprites part 2

* fixes

* more fixes

* a

* more para sprites + ntrsa voidhelm

* no more clown...
2024-05-06 23:23:27 -04:00
Ed
cc9e40820f Night on Europa (#27731)
night
2024-05-06 20:02:22 -07:00
PJBot
19aeff26ec Automatic changelog update 2024-05-07 01:49:23 +00:00
no
630a7a78ed Add ghost role raffles (#26629)
* Add ghost role raffles

* GRR: Fix dialogue sizing, fix merge

* GRR: Add raffle deciders (winner picker)

* GRR: Make settings prototype based with option to override

* GRR: Use Raffles folder and namespace

* GRR: DataFieldify and TimeSpanify

* GRR: Don't actually DataFieldify HashSet<ICommonSession>s

* GRR: add GetGhostRoleCount() + docs

* update engine on branch

* Ghost role raffles: docs, fix window size, cleanup, etc

* GRR: Admin UI

* GRR: Admin UI: Display initial/max/ext of selected raffle settings proto

* GRR: Make a ton of roles raffled
2024-05-06 18:48:16 -07:00
Jezithyr
6685146a1e Moved Serverside solution container code to shared (yes that includes ensureSolution!) (#27478)
* Added warning to tryGetSolution, moved SolutionContainer code to shared
- Added an optional warning (false by default) to print an error if a solution is missing when using tryGetSolution methods
- Moved ensuring solution containers to shared, left the old method stubs for compatability and marked them as obsolete.

* Update SharedSolutionContainerSystem.cs

* Update SharedSolutionContainerSystem.cs

* Update SolutionContainerSystem.cs

* Update SharedSolutionContainerSystem.cs

* Fixing ensuring chem solutions always returning false on client
- ensuring chem solutions will only return false on the client if it is waiting for a server solutionEntity to be synced

* Added concentration helpers

* fix whitespace
2024-05-06 17:27:36 -07:00
Ed
547e15a158 hair update (#139) 2024-05-07 01:10:12 +03:00
PJBot
008f6ef94a Automatic changelog update 2024-05-06 20:21:25 +00:00
Alzore
7794ab8609 Reduce the amount of burn damage from touching lights (#27728)
* chilled

* external
2024-05-06 13:20:19 -07:00
Alzore
7d23d01445 Half the amount of bleed rate cauterized by burn damage (#27726)
half
2024-05-06 13:19:57 -07:00
Ygg01
b58d8a02b6 Remove duplicate liar word id. Again (#27727)
Missed one translation
2024-05-06 18:02:50 +03:00
PJBot
ddb07d5f63 Automatic changelog update 2024-05-06 11:26:17 +00:00
Kara
aaabd5e914 Fix TryFindRandomTile grid weighting (#27724) 2024-05-06 04:25:11 -07:00
PJBot
8fa7ea7cf9 Automatic changelog update 2024-05-06 10:11:18 +00:00
Kara
8f4362df03 Event frequency balance pass (#27721)
balance
2024-05-06 03:10:12 -07:00
Ygg01
fbe8374c0f Remove duplicate liar word id (#27723) 2024-05-06 12:28:48 +03:00
Kara
aa426c9c3a Fix missing command desc (#27722) 2024-05-06 01:54:37 -07:00
PJBot
3dcb65feb2 Automatic changelog update 2024-05-06 08:18:41 +00:00
T-Stalker
026af631f8 New lobby art: Just a week away (#27717)
just a week away
2024-05-06 01:17:35 -07:00
Kara
c1aae2398b Round event frequency simulation command (#27718) 2024-05-06 00:33:30 -07:00
T-Stalker
b8d03b814b Update license of deadline.ogg (#27715) 2024-05-06 15:26:18 +10:00
metalgearsloth
13dbb95d45 Update submodule to 222.1.0 (#27714) 2024-05-06 14:22:59 +10:00
PJBot
3b3cc0e66c Automatic changelog update 2024-05-06 04:00:07 +00:00
0x6273
c7a5587e07 Dock device link port (#27646)
* Add dock device link port

* SpawnAndDeleteAllEntitiesInTheSameSpot moment

* The fuck is TryStopNukeOpsFromConstantlyFailing??

Do we have a new test that can randomly fail?
2024-05-06 13:59:01 +10:00
PJBot
1ecc36b049 Automatic changelog update 2024-05-06 03:52:40 +00:00
exincore
7ffa74abd0 fix(ui): Fix shuttle control radius marking text vertical spacing (#27695) 2024-05-06 13:52:35 +10:00
T-Stalker
104c2afe69 New Salvage song: Deadline (#27707)
Deadline
2024-05-06 13:51:33 +10:00
DrSmugleaf
eee8e03c15 Fix tests (#27711)
* Fix tests

* Fix test fail

* Apply same fix to other tests
2024-05-05 19:08:56 -07:00
DrSmugleaf
c20df3e39f Fix AlertControl throwing an error if the sprite view entity is deleted multiple times (#27690)
* Fix AlertControl throwing an error if disposed multiple times

* Replace default check with deleted check
2024-05-05 21:38:55 -04:00
PJBot
82fe5ab55d Automatic changelog update 2024-05-06 01:13:36 +00:00
Ty Ashley
b8144df7a5 Added new icons for the emote wheel (#27541)
* Added new icons for the emote wheel

* Corrected weh path

* Changed whistle to better match other vocal emotes. Modified honk icon to match dimensions of box. Corrected chirp and chitter emote icons.

* Cleaned up edges of icons

* Added attributions.yml to emotes folder
2024-05-05 20:12:30 -05:00
metalgearsloth
d1a5d35623 Expeditions audio tweaks (#27524)
- Now uses a SoundCollection.
- Now properly handles going between maps (audio rework mucho wow).
- GetAudioLength used so it can properly countdown ANY song (wow audio rework wow wow).
2024-05-06 10:19:43 +10:00
PJBot
254a9177fc Automatic changelog update 2024-05-05 23:33:50 +00:00
Mr. 27
93c5e86857 Add solution temperature to chemical analysis goggles (#27693)
yes
2024-05-06 09:32:43 +10:00
PJBot
b947490d08 Automatic changelog update 2024-05-05 23:31:13 +00:00
Killerqu00
7d35d54a81 welding masks on utility belts (#27694) 2024-05-06 09:30:06 +10:00
Vasilis
c61e683354 Remove useless line in runclient (#27701)
I forgor
2024-05-06 01:16:12 +02:00
metalgearsloth
2335be5e83 Update submodule to 222.0.0 (#27700) 2024-05-06 09:00:31 +10:00
Pieter-Jan Briers
4a2a63a86b Cache regex instances in most cases (#27699)
Using static Regex functions that take in a pattern is bad because the pattern constantly needs to be re-parsed. With https://github.com/space-wizards/RobustToolbox/pull/5107, the engine has an analyzer to warn for this practice now.

This commit brings most of content up to snuff already, though some of the tricker code I left for somebody else.
2024-05-06 08:57:32 +10:00
Verm
70d3cf7ba4 Emergency Tank + Plasma Can visible on suit storage slot (#27598)
* Suitstorage Sprites + Plasma tank slots

* Fix some extra brackets
2024-05-06 00:42:22 +03:00
Litogin
b1fca44b63 Bonfire whitelist (#137)
* Bonfire whitelist

* fix

* Update bonfire.yml

* Update tags.yml

* Update CP14Paper.yml

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
2024-05-05 23:53:47 +03:00
Vasilis
eb2fac40db Use dotnet run for the run batch files instead of directly calling the exe (#27698)
* Use dotnet run for the run batch files instead of directly calling the exe

* FUCK
2024-05-05 22:18:26 +02:00
PJBot
92c2ff0b05 Automatic changelog update 2024-05-05 14:43:41 +00:00
lzk
ead78b72d2 Add default whistle + whistles reorganize (#27676)
* Add default whistle + whistle reorganize

* aaa

* fux?

* fiiiiix???

* Revert "fiiiiix???"

This reverts commit 15353465d58db615185afa8c549e1819099c1a5b.

* Apply suggestions from code review

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>

---------

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
2024-05-05 16:42:35 +02:00
RumiTiger
45fc6bed2f Rename ChemCleanBoodstream.cs (#27691) 2024-05-05 09:37:10 -04:00
Nemanja
5183f3ed8b Scattershot antag fixes (#27429)
* scattershot antag fixes

* this too?

* dawg fuck this code

* ok so we kinda need this?
2024-05-05 19:23:43 +10:00
metalgearsloth
37d0cb9c90 Revert "npc can no longer attack you through a locker" (#27680)
Revert "npc can no longer attack you through a locker (#27677)"

This reverts commit 83b486b63f.
2024-05-05 19:22:33 +10:00
github-actions[bot]
2f3f917007 Update Credits (#27681)
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
2024-05-04 21:23:45 -04:00
Ed
2b6e12898b Corvax ctrl+c ctrl+v Russian localization (#135)
* Corvax ru localization

* remove Corvax stuff

* adventurer
2024-05-05 00:44:03 +03:00
Nim
f411126191 rifle (#134) 2024-05-05 00:43:56 +03:00
Pok
c3fe975e8b More descriptions for the beakers in the status panel (#27669)
Bottles

Descriptions for status panel
2024-05-04 22:07:29 +02:00
PJBot
4bb0786018 Automatic changelog update 2024-05-04 20:07:22 +00:00
Alzore
1c125cb14e Floodlights now have medium powercells instead of small (#27672)
mediumcellfloodlight
2024-05-04 22:06:16 +02:00
PJBot
0a15d08550 Automatic changelog update 2024-05-04 20:01:28 +00:00
Alzore
873799095c Security belts can now hold more items commonly carried by secoffs/HoS (#27674)
holobarrier
2024-05-04 22:00:22 +02:00
PJBot
8ee9ca2227 Automatic changelog update 2024-05-04 19:59:06 +00:00
Tyzemol
83b486b63f npc can no longer attack you through a locker (#27677) 2024-05-04 21:57:58 +02:00
Ed
6b173a4df5 Merge pull request #133 from crystallpunk-14/04-05-2024-upstream
04 05 2024 upstream
2024-05-04 21:35:22 +03:00
Ed
445f08ae07 Merge remote-tracking branch 'space-station-14/master' into 04-05-2024-upstream
# Conflicts:
#	Resources/Prototypes/Maps/Pools/default.yml
#	Resources/Prototypes/Maps/train.yml
2024-05-04 21:13:30 +03:00
Ed
72b8fcf99c Tiles rework (#131)
* tile restruct

* filter tiles

* Update ContentTileDefinition.cs

* oopsie

* Update migration.yml

* Update cave-arena.yml

* floors fix
2024-05-04 16:35:59 +03:00
PJBot
540c45cbe9 Automatic changelog update 2024-05-04 11:12:52 +00:00
Flareguy
0e829eb380 Vox customization fixes & updating (#27663)
vox customization
2024-05-04 04:12:11 -07:00
Ed
5ab1cc0c84 Pathological Liar (#27618)
* content

* upgrade

* n't

* ye ya

* Update speech-liar.ftl

* Mith replacement ideas

* fix

* more!

* Revert "more!"

This reverts commit 6d10bdf694985c525a2b451ed39380f975059b44.

* Update Content.Server/Speech/Components/ReplacementAccentComponent.cs

---------

Co-authored-by: Kara <lunarautomaton6@gmail.com>
2024-05-04 04:11:46 -07:00
PJBot
07d43af4a6 Automatic changelog update 2024-05-04 11:11:14 +00:00
Ed
e7d24b5648 Added Train station into map rotation (#27534)
* Update default.yml

* more sec
2024-05-04 04:10:08 -07:00
Agoichi
ba009f34fa Crystal/ punk-update (#129)
* Crystalpunk-update

* Crystalpunk-update

* Update Resources/Prototypes/_CP14/SoundCollections/hit_impacts.yml

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>

* Update Resources/Prototypes/_CP14/Entities/Structures/crystal.yml

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>

* Update Resources/Prototypes/_CP14/Entities/Structures/crystal.yml

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>

* clean up

* Update crystal.yml

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
Co-authored-by: Ed <edwardxperia2000@gmail.com>
2024-05-04 13:39:32 +03:00
Litogin
1d233226bb Animation of tails (#128)
Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
2024-05-04 13:31:14 +03:00
Ed
ba05b56d51 Fence fix + Navy revolver (#130)
* Update fence_wood.yml

* added revolver navy

* Update guns.yml

* Update wooden_fence.yml
2024-05-04 13:20:21 +03:00
Vasilis
1b3481f094 Rename Lizard urist (#27652) 2024-05-03 23:18:01 -07:00
Mr. 27
96a3967c3f Change return to continue in gamerulesystem (#27656)
Update GameRuleSystem.cs
2024-05-04 13:03:56 +10:00
PJBot
1d5392f86b Automatic changelog update 2024-05-04 00:04:58 +00:00
Mr. 27
6ecbf0a04c Fix some gamerules' round summary not working (#27654)
Update GameRuleSystem.cs
2024-05-03 20:03:52 -04:00
PJBot
960f268d1c Automatic changelog update 2024-05-03 20:24:49 +00:00
nikthechampiongr
6fc684812d Ninja's pinpointer tracks the research server (#27552)
Change the tracked component on the ninja's pinpointer from BecomesStation to Research Server
2024-05-03 22:23:43 +02:00
Ed
acd8f93b36 added Kocherga fences 2024-05-03 21:33:24 +03:00
Ed
dd84d48fed Refactors, bugfixs + Crystals (#127)
* fix dwarf displacement map

* Big Fireplace update

* add crystalls placeholder

* bonfire update

* displaccement update

* Update wallmount_torch.yml
2024-05-03 20:40:31 +03:00
PJBot
c045e2488e Automatic changelog update 2024-05-03 17:27:16 +00:00
Just-a-Unity-Dev
76ecdee946 Geras bug fixes (#27308)
* Geras bug fixes

* oops

* its as shrimple as that

toggled transferName in the polymorph yml instead of using the system to manually change it

* its as shrimple as that (2.0)

fixed reviews for zombies having a dummy action, instead - properly implemented removal of action

* its as shrimple as that (3.0)

fixed tests by removing nameidentifier from slime (its already inherited, anyway)
2024-05-03 19:26:09 +02:00
Ed
e5246f1e76 doors update (#126) 2024-05-03 18:22:10 +03:00
Ed
0450a416e2 Revert "Make immovable rod announce at the end of the event" and "Rod event has a proper annoucement" (#27645)
* Revert "Make immovable rod announce at the end of the event (#27587)"

This reverts commit efceaa89e0.

* Update immovable-rod.ftl
2024-05-03 04:10:24 -07:00
PJBot
bedec83cd9 Automatic changelog update 2024-05-03 07:52:39 +00:00
Jay
0056befd4b Allow EMP implants to be used while stunned or cuffed. (#27644)
Update types.yml
2024-05-03 09:51:33 +02:00
PJBot
40a4eeaa39 Automatic changelog update 2024-05-03 06:58:43 +00:00
Hanz
a8bf2689a4 Red bool update (#27597)
* the meat and potatoes

yuh yuh yuh

* what the hell is a copyright?

am I right?
2024-05-03 08:57:37 +02:00
Lamrr
a28296433b Fixes the grammar for the captain's supervisor (#27638)
Fixes the grammar on the captain's supervisor
2024-05-03 12:12:34 +10:00
PJBot
4ede46003a Automatic changelog update 2024-05-03 01:25:27 +00:00
Errant
f64dd5f45f Space Ninjas auto-toggle internals after spawning (#25083)
* fix engine version

* actually fix engine version

* Automatically activated breathing masks

* weh

* who needed that component anyway

* check if internals are already running

* Update Content.Server/Atmos/Components/BreathToolComponent.cs

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* Update Content.Server/Body/Systems/InternalsSystem.cs

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* prediction

* record struct event

* remove delayed activation, instead ensure that masks spawn last

* leftover

* engine version

* re-implement

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-05-03 11:24:21 +10:00
PJBot
192de3d9cb Automatic changelog update 2024-05-03 00:14:41 +00:00
Mr. 27
c69bf2f2aa Add syndicate sleeper agents random event (#27501)
* Intercept rule (#10)

* add

* b

* add this back lol

* fix test fails (alert levels dont have prototypes)

* tweaks
2024-05-03 10:13:35 +10:00
Leon Friedrich
f348e6aa30 Add EntityWhitelistSystem (#27632)
* Add EntityWhitelistSystem

* Sandbox fix

* update test
2024-05-03 10:10:15 +10:00
PJBot
291ecf9643 Automatic changelog update 2024-05-03 00:04:58 +00:00
Plykiya
71dbb955ce Increase Blast Grenade Recipe Cost and Add Research Requirement (#27580)
* Adjust blast grenade recipe

* Move blast grenades into tier 2 research

* Move blast grenades to dynamic recipes for secfab and autolathe

---------

Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-05-03 10:03:52 +10:00
PJBot
f76a471e5a Automatic changelog update 2024-05-02 23:38:26 +00:00
Leon Friedrich
3c3c2daf26 Fix UI interaction priority (#27631) 2024-05-03 09:37:20 +10:00
Ed
f9204832d2 Merge pull request #125 from crystallpunk-14/02-05-2024-upstream
02 05 2024 upstream
2024-05-02 21:01:59 +03:00
Ed
7d11ff5562 Merge remote-tracking branch 'space-station-14/master' into 02-05-2024-upstream 2024-05-02 20:46:45 +03:00
Ed
4c692d7d4a Alchemy + Guidebook initialization (#124)
* remove Guidebook

* water and blood

* localization things

* added vital extract

* some fixes

* added bloodgrass

* guidebook localization

* fixes icons and remove unnecesary fields

* added inhand cauldron

* fix wallmount board

* Update bonfire.yml

* Update bonfire.yml

* alchemy furnace + mist

* fixes

* Guidebook localization

* Update drinks.yml

* Revert "remove Guidebook"

This reverts commit 7924cf235f.

* fix filtering guidebook

* test fix

* Update heater.yml
2024-05-02 20:41:11 +03:00
PJBot
8a7f709794 Automatic changelog update 2024-05-02 17:10:44 +00:00
Tayrtahn
9b17693396 Fix SpawnItemsOnUse not playing sound (#27621)
Made SpamItemsOnUse play sound at entity coordinates instead of parenting
2024-05-02 13:10:20 -04:00
deltanedas
8909dc7d40 make ducky slippers waddle (#27628)
Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-05-02 20:09:38 +03:00
slarticodefast
eab276a12d small SpawnItemsOnUse cleanup (#27625)
* small SpawnItemsOnUse cleanup

* that one was not needed
2024-05-02 20:08:26 +03:00
PJBot
09b6f5c128 Automatic changelog update 2024-05-02 16:18:43 +00:00
Lamrr
b728f36f30 Wine and beer bottles can be inserted into booze dispenser (#27626)
Fixes tags on wine and beer bottles
2024-05-02 12:17:36 -04:00
PJBot
64a732ad7b Automatic changelog update 2024-05-02 14:50:59 +00:00
Vasilis
a4b0a34bc7 Remove airtight flaps from the construction menu (#27619)
They are meant to be mapping only items.
2024-05-02 10:49:53 -04:00
PJBot
235091b377 Automatic changelog update 2024-05-02 12:38:18 +00:00
Michael
131c269e2b Improve CMO's lab coat (#27551)
This Aims at balancing the viability of the CMO's lab coat compared to his other available options, those being his winter coat (which is just a straight up upgrade) and his hardsuit.

and also its suppose to level him with RD since RD's lab coat has special rad protection

Co-authored-by: Michael <107807667+Bugfinder1@users.noreply.github.com>
2024-05-02 15:37:12 +03:00
PJBot
ce3ba577e0 Automatic changelog update 2024-05-02 12:36:17 +00:00
nao fujiwara
316a3d7f4d added a bunch more fox noises (#27578)
* fuck it we ball

* added recommended copyright information

* revised copyright license

* revised copyright license x2

* finalized the fops

# reduced the number of audio clips
# adjusted the volume of all fox sounds to be consistent with each other

* added new sounds to the overall fox parent mob because we forgot oopsie
2024-05-02 14:35:10 +02:00
PJBot
b90a58d88b Automatic changelog update 2024-05-02 12:33:57 +00:00
Mr. 27
6680bd4c60 emote wheel fixes (#27545)
* cheese

* Update disease_emotes.yml
2024-05-02 15:33:51 +03:00
Plykiya
70f734edcc Disarm throws item in random direction (#27589)
* Disarm throws item in random direction

* Slightly increased offset

* Return the return

---------

Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-05-02 15:32:47 +03:00
Tayrtahn
236da1cd27 Make UseDelay SetLength do EnsureComp (#27601)
Make UseDelay.SetLength do EnsureComp
2024-05-02 22:16:16 +10:00
PJBot
05f0fddf5d Automatic changelog update 2024-05-02 06:24:28 +00:00
Repo
17304068b4 Track Admin Game Time (#24945)
* AdminTime tracked

* Attempts to fix PR issues.

* Admin afk logic update
2024-05-01 23:23:22 -07:00
PJBot
889b578e56 Automatic changelog update 2024-05-02 06:01:07 +00:00
Leon Friedrich
fd9894164f Fix Gas Analyzers not opening (#27610) 2024-05-02 16:00:01 +10:00
Leon Friedrich
a7e6337cbd Replace NavMap dictionaries with int[] (#27602)
* Replace NavMap dictionaries with int[]

* Remove badly named const

* Remove unnecessary offset

* Prioritize airlocks
2024-05-02 12:51:21 +10:00
PJBot
11a4f9d21f Automatic changelog update 2024-05-02 02:41:13 +00:00
metalgearsloth
5053c8afdb Fix effects (#27533)
* Fix effects

- Fix muzzle flash rotations.
- Fix effects so they update every frame.
- Fix effects tanking client performance.

* Fix merge artifact
2024-05-02 12:40:07 +10:00
metalgearsloth
6596584722 Update submodule to 221.2.0 (#27603) 2024-05-02 12:27:08 +10:00
PJBot
05be6d376d Automatic changelog update 2024-05-02 00:19:44 +00:00
metalgearsloth
7ba228732d Optimise navmaps significantly (#27528)
* Optimise navmaps significantly

- Reduce the delta state size significantly.
- Remove AirtightChangedEvent because this will spam them out constantly.

* weh

* review

---------

Co-authored-by: ElectroJr <leonsfriedrich@gmail.com>
2024-05-02 10:18:38 +10:00
PJBot
a95b0d000a Automatic changelog update 2024-05-01 22:27:28 +00:00
lzk
efceaa89e0 Make immovable rod announce at the end of the event (#27587) 2024-05-01 18:26:22 -04:00
PJBot
52ad84c397 Automatic changelog update 2024-05-01 22:24:48 +00:00
Simon
c00987500f Add DoorBumpOpener to BaseMobAdultSlimes (#27591) 2024-05-01 18:24:31 -04:00
FungiFellow
7cd1e4e30d Grilles now take Structural Damage (#27596)
damageContainer: Inorganic -> StructuralInorganic
2024-05-01 18:23:42 -04:00
Ciac32
cf633b4849 Enforce inequality between different species (#27586)
Fix missing species check in humanoid equality operation
2024-05-01 13:01:15 -04:00
Ed
2c34befbcb Fireplace (#123)
* bonfire!

* fix

* update torch

* docs

* add audio, fix errors

* loc string + fix errors
2024-05-01 19:55:48 +03:00
ShadowCommander
577106251b Fix pinpointer errors for missing sprite layer (#27582) 2024-05-01 11:51:12 -04:00
PJBot
2b33cb9a47 Automatic changelog update 2024-05-01 15:25:11 +00:00
NotSoDana
9ca1d01218 Gildlager empty bottle fix (#27581)
* rename goldschlager bottle

* migration

* fix rsi
2024-05-01 11:24:05 -04:00
PJBot
b9cf9c1d60 Automatic changelog update 2024-05-01 15:18:54 +00:00
Ciac32
648472233c Fix antag verb incorrectly giving role to admin player instead of target (#27584)
Fix antag verb giving role to admin player instead of target
2024-05-01 11:18:32 -04:00
Plykiya
6e1f0ba390 Make insert telecrystal message only show to player (#27585)
Restrict message to player and fix grammar

Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-05-01 11:17:47 -04:00
deltanedas
ff762e56a7 add ghostnado button to warp menu (#27556)
* add ghostnado button to warp menu

* translator ops

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-05-01 06:59:35 -07:00
Verm
133d9280ae Add correct lawyer bags to loadouts (#27573)
* add lawyerbackpack to locale

* lawyer backpack group

* Add bags

* add loadout group

* Be less lazy and spot formatting problems
2024-05-01 18:48:28 +10:00
PJBot
99130ff332 Automatic changelog update 2024-05-01 03:28:27 +00:00
Ciac32
b160c42926 Fix Loadout Editor not closing when Character Editor is closed. (#27539)
Remove duplicate UpdateRoleRequirements call screwing up update ordering
2024-05-01 13:28:13 +10:00
K-Dynamic
446f516590 Simplified and consistent honkbot & jonkbot recipes (#27535)
simplified honkbot & jonkbot recipes
2024-05-01 13:27:21 +10:00
DrSmugleaf
5548d90f0d Add explosion.can_create_vacuum cvar (#27548) 2024-05-01 13:11:27 +10:00
no
81e553401c Make female reptilians use female cry sound instead of male (#27563) 2024-05-01 13:09:31 +10:00
DrSmugleaf
c57164211b Update Patrons.yml (#27560) 2024-04-30 18:20:39 -07:00
lzk
c0e3c4fac7 add noSpawn: true to tippy (#27538) 2024-05-01 01:07:30 +03:00
Psychpsyo
0d88a1fd7d Fix sprite for coder socks (#27553) 2024-04-30 17:54:50 -04:00
metalgearsloth
2a0fe88aaf Reduce rusty wall occurrences (#27522)
Every station looks like barratry as there will be many rusty walls onscreen everywhere.
2024-04-30 17:54:22 -04:00
Jezithyr
6869adfa78 Move GasMixture to shared (#27480)
* Moved GasMixture to shared

* Temp Fix for sandbox violation, idk why Array.Resize isn't working properly. It's already sandboxed.

* The most powerful webedit in history
2024-04-30 14:31:05 -07:00
Jezithyr
b8c0372ac6 Update submodule to v221.1.0 (#27554) 2024-04-30 14:01:09 -07:00
Errant
c3a0ba9dd8 Size-based entity whitelist (#26798)
* Size based whitelisting

* namespace and misc refactor

* modern datafields, what will they think of next

Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>

* the future is now

Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>

* Update TagSystem to work with ProtoId lists

* I guess someone might run into these too, one day

* copypaste moment

* update to sawmill

* Okay, but what if it just worked

---------

Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
2024-04-30 11:06:56 -04:00
Ed
0169cb55d8 Alchemy instruments (#122)
* add beer barrel

* add vet

* add storage to vat

* make bucket viable!

* bandage vat item fix

* Update vat.yml

* add small vial

* tiny vial

* Update SharedStorageSystem.cs

* Create biological.yml

* spilable and bonfire climbing
2024-04-30 16:48:08 +03:00
PJBot
046d062230 Automatic changelog update 2024-04-30 12:15:12 +00:00
ERROR404
e57f5fadc5 Add chameleon projector in thief toolbox (#27491)
Base
2024-04-30 15:14:06 +03:00
Magnus Larsen
f1c36af0a5 Fix Melee swing effect rotation (#27494)
* Melee swing effect: Allow rotation

* Make melee weapon effects follow the user
2024-04-30 21:56:41 +10:00
T-Stalker
bf3e9fe3b4 Add neckfull frills for lizards (#27523)
* light

* neckfrills

* Delete Resources/Prototypes/XenoArch/Effects/normal_effects.yml

* Revert "Delete Resources/Prototypes/XenoArch/Effects/normal_effects.yml"

This reverts commit 6e6fad609a66a0615abcd545009cdb2f52c9b955.

* Revert "light"

This reverts commit d1f111d4c64da4d2a64907f7dfead104892d1462.

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-30 19:18:00 +10:00
PJBot
d30b12708d Automatic changelog update 2024-04-30 06:50:42 +00:00
T-Stalker
d9d36b050a Makes flares quieter (#27521)
* light

* flares quieter
2024-04-30 16:49:35 +10:00
Mr. 27
a7bf9583dd monkeys get a different deathgasp emote (#27497)
a
2024-04-30 00:14:45 -04:00
Mr. 27
0c8a499a66 give cap sabre the cane blade noises (#27508)
Update belts.yml
2024-04-30 00:13:56 -04:00
PJBot
44e6f3f5db Automatic changelog update 2024-04-30 04:06:20 +00:00
T-Stalker
4b55f01c55 Rod event has a proper annoucement (#27515)
roddies
2024-04-29 21:05:14 -07:00
PJBot
d85d9fbbd1 Automatic changelog update 2024-04-30 03:02:43 +00:00
lzk
9631fee7f2 Remove barozine from mutatuion (#27512)
Remove barozine from mutatuib
2024-04-30 05:01:38 +02:00
PJBot
2e3fd3114b Automatic changelog update 2024-04-30 00:20:13 +00:00
ShadowCommander
dfa365f701 Fix microwave construction (#27500)
The microwave system would update UserInterface on any container changed instead of just the microwave_entity_container. This would cause it to error when trying to update the UI when ConstructionSystem inserted the circuit board and components.
2024-04-29 20:19:07 -04:00
KittenColony
4b39c358c8 Fix sprite for frontal splotch snout (#27479)
frontal sprite fix
2024-04-29 17:30:38 -04:00
Ed
91028a5149 remove Injector SolutionName constant (#27493)
remove stupid constant
2024-04-29 17:29:15 -04:00
PJBot
2cfc12c134 Automatic changelog update 2024-04-29 17:10:36 +00:00
FungiFellow
657d9ab740 Syndi-Cat QoL Changes (#27408)
* Syndi-Cat Wideswing, Shoes, and Explosion Resist

* Damn you Plykiya

* 10/10Pierce/Structural -> 6/6/15 Pierce/Slash/Structural

* Update animals.yml
2024-04-29 20:09:30 +03:00
Ed
743c732162 Merge pull request #121 from crystallpunk-14/29-04-2024-upstream
29 04 2024 upstream
2024-04-29 16:39:56 +03:00
Ed
9520f63aa1 Merge remote-tracking branch 'space-station-14/master' into 29-04-2024-upstream
# Conflicts:
#	Resources/Prototypes/Entities/Mobs/Customization/Markings/human_hair.yml
2024-04-29 16:28:04 +03:00
Ed
098111948e Disposal aftermerg fix (#27488)
* wtf

* fix

* delta fixes

* Update ThrowInsertContainerSystem.cs
2024-04-29 23:26:28 +10:00
PJBot
5dda487db4 Automatic changelog update 2024-04-29 13:13:36 +00:00
Ed
bf8002569c Throwing into disposals logic splitting (#27487)
* wtf

* fix
2024-04-29 23:12:42 +10:00
DrSmugleaf
6b5e99f5eb Make bullets inherit the velocity of the grid, not the gun or player (#27484) 2024-04-29 23:12:29 +10:00
metalgearsloth
386454706b Fix snappop (#27264)
* Fix snappop

Bunch of stuff slipped through.

* name
2024-04-29 19:54:40 +10:00
Nemanja
e2087115af Fix position swapping with QSI and artifacts (#26364) 2024-04-29 19:11:07 +10:00
metalgearsloth
569253940f Update submodule to 221.0.0 (#27477) 2024-04-29 19:09:43 +10:00
Leon Friedrich
3c154abb5b Content changes for engine exception tolerance PR (#27455)
* Content changes for engine exception tolerance PR

* Poke tests
2024-04-29 18:43:15 +10:00
metalgearsloth
6d619c9420 Tippy fixes (#27475)
How does that UISystemDependency not crash.
2024-04-29 18:41:58 +10:00
PJBot
5aece1679a Automatic changelog update 2024-04-29 08:37:24 +00:00
Leon Friedrich
6471f55a49 Action UI fixes (#27468) 2024-04-29 18:36:18 +10:00
PJBot
0ab5696391 Automatic changelog update 2024-04-29 06:39:45 +00:00
Plykiya
7dae58c9f8 Late join thieves! (#27466)
Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-04-28 23:38:38 -07:00
Kara
f59a4f2a86 Make events generally much more common (#27469)
Make events generally more common
2024-04-28 23:38:14 -07:00
PJBot
571cff8cab Automatic changelog update 2024-04-29 04:53:41 +00:00
KrasnoshchekovPavel
199e05fb34 fixed formatting of floating point numbers during localization (#27441) 2024-04-28 21:52:35 -07:00
PJBot
4c66e4f9dc Automatic changelog update 2024-04-29 04:39:38 +00:00
MilenVolf
7ee18433c8 New borg sounds (#27205)
* New borg sounds

* Add manic laughter of an assault borg

Never wanted, but needed

* Fix wrong attribution

* Some requested changes

* Change borgwalk sounds

* Forgor
2024-04-28 21:38:31 -07:00
Morb
16b3e2233a Emotes Menu (#26702)
* Basic emote radial menu

* Move out from corvax

* Move to UI controller & add to top menu bar and key bind

* Make emote play

* Add name localization for emotes

* Localize chat messages

* Fix emote menu

* Add categories localization

* Fixes

* Fix

* Add emotes entity blacklist

* Fix entity whitelist required all logic

* Remove unused wagging emote

* Revert sprite

* Set default texture for emote icon

* Update Resources/keybinds.yml

---------

Co-authored-by: Kara <lunarautomaton6@gmail.com>
2024-04-28 21:38:23 -07:00
SlamBamActionman
373c368b94 Tippy, the helpful hint clown! (#26767)
* Tippy is BACK

* Clean up clippy from aprils fools

* Changed names from clippy to tippy, added localization, removed local_clippy command, made it easier to target a specific player

* Rename clippy.yml to tippy.yml

---------

Co-authored-by: Kara <lunarautomaton6@gmail.com>
2024-04-28 21:38:16 -07:00
lzk
eb9ee4541f Add more telecomms variations (#26822)
* Add more telecomms variations

* fox :fox:

* oops
2024-04-28 21:26:17 -07:00
TsjipTsjip
aab103865e Update PR Labeler to v5 (#26845)
* Update PR Labeler to v5

* Change conflict labeler.

* Implement draft filtering functionality

* Actually, pull_request_target is appropriate here.
2024-04-28 21:23:49 -07:00
PJBot
328134ab18 Automatic changelog update 2024-04-29 04:17:10 +00:00
Mangohydra
8afae8a1f1 Martyr Cyborg Module, borg law 2 explode (#25815)
* borg law 2 explode

* attributions fix + CL fix

* please dear god work i beg you

* maybe this will work :godo:

* 50% off deal + disc change

* absolving merge conflict

* merge conflict fix

* Update Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml

* Update Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml

* Update Resources/Audio/Effects/Grenades/SelfDestruct/attributions.yml

* Apply suggestions from code review

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: Kara <lunarautomaton6@gmail.com>
2024-04-28 21:16:04 -07:00
PJBot
16f65f42fc Automatic changelog update 2024-04-29 04:14:20 +00:00
Gotimanga
eb41f1da5f Adding new Cryogenics Reagent - Opporozidone (Attempt 2) (#24074)
* Fixing mistakes

* How did I make the same mistake twice

---------

Co-authored-by: Kara <lunarautomaton6@gmail.com>
2024-04-28 21:13:14 -07:00
PJBot
5f216ef1ee Automatic changelog update 2024-04-29 04:07:33 +00:00
Leon Friedrich
7c7d8eb645 ActivatableUI tweaks (#27448)
* ActivatableUI tweaks

* EntGotRemovedFromContainerMessage

* A
2024-04-29 14:06:43 +10:00
potato1234_x
cd90c05ce5 Rainbow Weed (#25759)
* rainbow weed

* Lipolicide

* psicodine + mannitol

* happiness

* ground + dried + smokables

* damn you notepad++

* fix

WHY NOT TELL ME ALL THE PROBLEMS AT THE SAME TIME!!!

* work

* work i beg you

* recipe good

* possibly fix merge conflict

* remove reagents
2024-04-28 21:06:27 -07:00
Kukutis96513
9cb3287de4 Senior physician sleeve symmetry (#27016)
* weh.

* get the weh out of my repository

* add best lizard figurine

* remove umbra stuff from master

* sprite time!!

* revert stuff?

* newer spritesss
2024-04-29 00:02:46 -04:00
Leon Friedrich
8f1a44fe05 Prevent SecretRule from picking invalid presets (#27456)
* Prevent SecretRule from picking invalid presets

* remove lonely semicolon

---------

Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
2024-04-29 00:00:41 -04:00
PJBot
2393ce1ceb Automatic changelog update 2024-04-29 03:39:51 +00:00
Hanz
33e1752a49 HoP and QM Stamps (#25604)
the meat and potatoes

yup
2024-04-28 20:38:45 -07:00
PJBot
511d8a7267 Automatic changelog update 2024-04-29 03:37:17 +00:00
Magnus Larsen
5118865d47 Allow more items to be recycled (#24435)
Give more items a PhysicalComposition for recycling
2024-04-28 20:36:11 -07:00
Leon Friedrich
1eb81427d3 Stop admin verb pop-in (#27450) 2024-04-29 13:24:10 +10:00
Leon Friedrich
a466b35b27 Move UnpoweredFlashlight to shared (#27449) 2024-04-29 13:22:11 +10:00
PJBot
a1b12f95a5 Automatic changelog update 2024-04-29 03:09:47 +00:00
beck-thompson
cdd900cef6 Infinate chem dupe fixed (Toilet, drain) + dirty water toilet fix (#27446)
innital commit
2024-04-29 13:08:41 +10:00
Plykiya
405e020bfa Fix doubled gas mask action message (#27463)
Fix doubled message

Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-04-29 13:02:30 +10:00
PJBot
757d59cbdd Automatic changelog update 2024-04-29 02:46:00 +00:00
Plykiya
4416a21dd5 Make Smile the Slime grabbable like geras (#27458)
Make smile grabbable like geras

Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-04-29 12:44:54 +10:00
beck-thompson
2135cbdb23 Fixed some mop .ftl capitalization (#27447) 2024-04-29 02:26:44 +02:00
Ed
6cb97502aa KBAS5 clothing + Jaraten Structures (#120)
* add barbarian clothes

* add jaraten floors and wall

* locale

* add stonebrick walls and gold\silver ore cave walls

* fix brick black, update cave arena

* Update roundstart.yml

* Update cave-arena.yml
2024-04-28 22:47:01 +03:00
PJBot
f89133b3ad Automatic changelog update 2024-04-28 11:08:42 +00:00
Ubaser
008935f6ec New plant mutation: Pyrotton (#27200)
* WIP

* sprites n stuff

* flavour

* maybe fix

* add stack

* fix parent
2024-04-28 13:07:36 +02:00
PJBot
5476daf64e Automatic changelog update 2024-04-28 09:29:21 +00:00
osjarw
f3e9db0141 DelayedForce and Rapid anom behaviors fixed (#27435) 2024-04-28 12:28:16 +03:00
PJBot
ab66ae9ab0 Automatic changelog update 2024-04-28 08:24:34 +00:00
FungiFellow
1efdf4a40a Bows fit on Airtank Slot (#27433)
Update bow.yml
2024-04-28 18:23:28 +10:00
PJBot
18fa8bf633 Automatic changelog update 2024-04-28 07:12:52 +00:00
Plykiya
0efcd30ac6 Hardsuits, EVA suits, Firesuits, and others now protect your feet from Glass Shards (#26764)
* Hardsuits and softsuits count as having shoes for step triggers

* Add softsuit tag prototype

* Change to suitEVA tag

* Get rid of softsuit tag, found suitEVA tag

* Full pass of ShoesRequiredStepTriggerImmune

* Adds check to outerClothing for ShoesRequiredStepTriggerImmune

* return

* fuck Dionas

* Convert to comp, space dragons immune as well

* Merge conflict

* Merge conflict

* fix leftover tags

* empty spaces

* turns out the dragon didn't need it

* minor optimization

* Add access for system, add comp to baseShoes, check slotflags for every slot besides pockets

* fix

* fuck it we ball

---------

Co-authored-by: Plykiya <plykiya@protonmail.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-28 17:11:46 +10:00
Plykiya
db200faf11 yml fix for locker deconstruction (#27430)
Actual fix for lockers and deconstruction

Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-04-28 16:22:10 +10:00
PJBot
cbb2554c94 Automatic changelog update 2024-04-28 06:13:51 +00:00
exincore
faa7f3461c feat(fax): Fax machines print, copy, and send paper labels (#25979)
* feat(fax): Client fax file-print parses and stores label

* feat(fax): Fax machines print, copy, and send paper labels

* style(Fax): Comments and formatting

* feat(fax): Make fax admin logging more consistent and clear

* refactor(fax): Replace ternary with a simpler null coalescing

* refactor(fax): Make FaxSystem Send method signature consistent with Copy, PrintFile

* refactor(fax): Read entire file and process later instead of peeking first

* refactor(fax): Remove local variables only used for style

* style(fax): Fix some nearby style errors

* fix(fax): Undo an inaccurate change to admin log formatting

* refactor(fax): Separate `firstLine` variable

* fix(fax): Use Environment.NewLine

* bienvenidos

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-28 16:12:45 +10:00
PJBot
5c817ddfc1 Automatic changelog update 2024-04-28 05:50:09 +00:00
Boaz1111
a8c297a374 Hyperconvection Circuit Imprinter (#27283)
* not done yet

* i may be stupid

* Update electronics.yml

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-28 15:49:03 +10:00
PJBot
47c5f0dba3 Automatic changelog update 2024-04-28 05:47:59 +00:00
Boaz1111
fe8ad485f2 Circuit imprinter now uses less glass (#27310)
* moved from 9 sheets of glass to 5 sheets of glass for all circuit recipes

* Revert "moved from 9 sheets of glass to 5 sheets of glass for all circuit recipes"

This reverts commit 45bb8d40150cddbbe005f5d66d34532b79143f98.

* adresses merge conflict

* fixed error

* parents base computer board to base machine board

* Revert "parents base computer board to base machine board"

This reverts commit dec3a799a90b4a0cb121b6694ecf65d9a0abd6a3.

* other thing was causing errors, guess it's this now
2024-04-28 15:46:53 +10:00
SlamBamActionman
f544c91298 Revert Exterminator pending newmed/redesign (#26978)
* Reverts Exterminator

* Includes commented out parts + sprites

* Readd stuff, comment out yaml

* Popup ads

* review

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-28 15:45:54 +10:00
PJBot
d90cba6eed Automatic changelog update 2024-04-28 05:28:02 +00:00
Nemanja
783d3a9aa8 Actual fix for lockers and deconstruction (#27431)
actual actual locker construction fix
2024-04-28 15:26:55 +10:00
PJBot
ee35fb12a7 Automatic changelog update 2024-04-28 05:05:54 +00:00
Keer-Sar
9f747485e9 Medal case whitelist (#27428)
* Create Medal tag and assign tag to medals

* Update Resources/Prototypes/tags.yml

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-28 15:04:49 +10:00
PJBot
afbbcd35fa Automatic changelog update 2024-04-28 04:49:25 +00:00
KrasnoshchekovPavel
3fcbbc0732 Added localization of groups and types: damage, metabolism (#27368)
* Added localization of groups and types: damage, metabolism (displayed in the guide book). The text for the health analyzer, weapon damage inspection is now taken from damage prototypes

* fix damage tests

* fix damage test yml

* fix damage test prototypes

* Update Content.Shared/Damage/Prototypes/DamageGroupPrototype.cs

* Update Content.Shared/Damage/Prototypes/DamageTypePrototype.cs

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-28 14:48:19 +10:00
RumiTiger
f5b8b5fbdc Sprites for drinks without sprite (attempt 2) (#27227)
* A beer can and a wine can

* fix wrong file locations


---------

Signed-off-by: c4llv07e <kseandi@gmail.com>
Co-authored-by: c4llv07e <kseandi@gmail.com>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-28 14:43:45 +10:00
PJBot
f88b6f6154 Automatic changelog update 2024-04-28 04:41:13 +00:00
NotSoDana
f5aa5f1f22 Several new bartender tools (#27406)
* added bar specs

* specs in boozeomat

* added jigger in bartender guide

* fixed ice bucket

* cdn

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-28 14:40:07 +10:00
metalgearsloth
72f790844f Fix recharger (#27426) 2024-04-28 14:39:42 +10:00
metalgearsloth
d66ad739ee Fix godmode serialization (#27427)
IDK
2024-04-28 14:30:39 +10:00
PJBot
09379a5c77 Automatic changelog update 2024-04-28 04:20:36 +00:00
osjarw
a4504e2fef Fix handlabeler/utility belt misprediction (#26660)
* Fix handlabeler/utility belt misprediction

* Partly moved HandLabelerSystem to shared
And cleaned up HandLabelerComponent

* WIP format the files so later commits look clearer
Doesn't change individual code lines, but may move
functions to another file

* WIP some more code movement

* Hand Labeler is now mostly predicted
Only the UI isn't

* WIP: Formatting and moved stuff

* Using componentstates for prediction correction

* review

* Update label on label change

* Don't overwrite label while editing

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
Co-authored-by: ElectroJr <leonsfriedrich@gmail.com>
2024-04-28 14:19:30 +10:00
PJBot
1c78f60bc3 Automatic changelog update 2024-04-28 03:20:39 +00:00
icekot8
a7ad59f6ba Portable Recharger: Arsenal T3 (#26655)
* sys

* item

* ahm.

* Update Content.Server/Power/Components/ChargerComponent.cs

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-28 13:19:33 +10:00
PJBot
49d8fe33a3 Automatic changelog update 2024-04-28 03:04:02 +00:00
Plykiya
a478446e5a Printable Special and Empty Mags for Autolathes (#27396)
* Change emag recipes to print mags instead of single ammo

* Get rid of useless single ammo printing recipes

* Add in submachine gun mags

* missing magazine shotgun beanbag in nonlethal research

* Sort lathes that use ammo crafting recipes alphabetically

---------

Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-04-28 13:02:56 +10:00
Ed
f079e77554 Displacement maps now works on any layers (#27405)
* try

* pipupi

* Update ClientClothingSystem.cs

* Update vox.yml

* Update ClientClothingSystem.cs
2024-04-28 12:35:40 +10:00
PJBot
599a66230b Automatic changelog update 2024-04-28 02:26:25 +00:00
Plykiya
be09520aa5 Reduce selection of traitor max from 12 to 8 (#27415)
TOO MANY DAMN SYNDIES

Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-04-28 12:25:19 +10:00
github-actions[bot]
02d2611d94 Update Credits (#27413)
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
2024-04-27 18:21:52 -07:00
Ed
33d04ef35b Dwarf species (#119)
* add dworf sprites

* dwarf prototypes

* add shoes displacement. FUCK! its doesnt work

* spaces

* footfix

* final dwarf!

* fixes
2024-04-28 01:44:43 +03:00
Agoichi
353fcd9cfe Magic Flashlight (#116)
* fucking flaslight

* flaslight

* Update objects.ftl
2024-04-28 00:56:02 +03:00
PJBot
9ccf95e333 Automatic changelog update 2024-04-27 19:11:52 +00:00
SlamBamActionman
2cb421bc43 Fix suit baldness (#27404)
Initial commit
2024-04-27 13:10:47 -06:00
PJBot
1d2335699d Automatic changelog update 2024-04-27 19:09:44 +00:00
RiceMar1244
8869fc3bb2 Resprite antique laser pistol (#27037)
* Resprites the captain's antique laser pistol

* Adds artist credit

* Improves icon outline and shading

* Replaces new sprites with something more resembling the in-game version
2024-04-27 13:08:38 -06:00
Nim
64218bfcab Coffin (#118)
* coffin

* eng
2024-04-27 22:04:52 +03:00
Terraspark4941
34ab1e760d The Honored Quran (Sprite addition) (#27400)
The Honored Quran
2024-04-28 02:36:04 +10:00
PJBot
7c2ea18088 Automatic changelog update 2024-04-27 16:34:03 +00:00
metalgearsloth
74041cf66f Fix literally every single activatable UI bug (#27401)
* Fix all activatable bugs

Apparently this was a load-bearing nullable enum.

* build
2024-04-28 02:32:57 +10:00
nao fujiwara
8a59e9e1f8 repositioned spooky long hair to its proper place in the alphabet (tweak) (#27370)
* repositioned spooky long hair to its proper place in the alphabet

* forgot the meta.json for hairstyles oopsie
2024-04-27 16:58:14 +02:00
Ed
2cefd0ee10 Displacement Map Visualizer QoL (#27392)
* Update Displacement Map Visualizer.lua

* Add files via upload

* Fix background layer being offset

This was caused by not taking the cel's own bounds into account.
Aseprite doesn't make an image layer "full size" if it only covers a
small part of the sprite.

---------

Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
2024-04-27 16:55:28 +02:00
PJBot
2621e31343 Automatic changelog update 2024-04-27 13:54:22 +00:00
MilenVolf
974129689c Glass box fixes + Construction & Stealthy deconstruction (#25365)
* Showcase update

* Fix craft prototype. Add glass box deconstruction for stealth gameplay

* Remove duplicated tag

* Forgor

* Some cleanup

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-27 23:53:16 +10:00
PJBot
c56f98f99f Automatic changelog update 2024-04-27 13:52:03 +00:00
brainfood1183
c0ce5fba2a Rodents can be Faxecuted (executed via Fax machine) (#21461)
* Rodents can be Faxecuted (executed via Fax machine)

* use brute instead of new group.

* fax visuals now use tags for mouse and hamster instead of comps

* fix for ubuntu, damn ubuntu bane of my life

* cant copy hamlet, can now faxecute mothroaches.

* fix

* fix

* fixes

* removed ifs now using switch, removed hastag now using string.

* fixes and no more switch

* cleanup

* more cleanup

* fix

* cleanup

* moved damage out of faxmachine and into own system and component.

* changes

* fixes and done i think.

* tidy

* Fixes

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-27 23:50:57 +10:00
PJBot
37105b3400 Automatic changelog update 2024-04-27 13:28:24 +00:00
Ramlik
db555a7c79 Add a handy security radio (#25913)
* Add a handy security radio

I've always wanted to have a handy security radio in game and I thought it would be cool to have one in game.

Demonstation can be found in here: https://youtu.be/VQOLiTQAmKc

* Merged radio files and changed sprite location

* Fixed RSI not having license and copyright

* Added a chance to spawn in security closets

All security closets will have 50% chance to spawn a handy security radio in it

* Update radio id

Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com>

* Change id in locker spawn

* Change id in locker spawn

* Changed id to RadioHandheldSecurity as suggested

* Add radio to vending machine instead of locker

Removed radio from lockers and added it to security vending machine

* Fixed radio not having a sprite

---------

Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com>
2024-04-27 23:27:18 +10:00
metalgearsloth
6d3e788dd6 Update cane UI key (#27395)
* Update cane UI key

* none of the pr passed ci yippee

* weh
2024-04-27 23:17:23 +10:00
Ed
d4556c2657 Merge pull request #117 from crystallpunk-14/ed-27-04-2024-displacement-upstream
Ed 27 04 2024 displacement upstream
2024-04-27 15:21:33 +03:00
Ed
3f508c899d ui fixes 2024-04-27 15:08:25 +03:00
Ed
1c38d46cd3 fixes 2024-04-27 14:48:55 +03:00
PJBot
3a198cbb0d Automatic changelog update 2024-04-27 11:18:52 +00:00
Tainakov
6d6e7f0c98 [Admin QOL] +Adminchat flag (#26930) 2024-04-27 13:17:46 +02:00
PJBot
4d223f2efd Automatic changelog update 2024-04-27 10:40:05 +00:00
Plykiya
cafb41c161 Printable Special Mags and Empty Mags and Material Rebalance for Ammo (#26178)
* Printable Empty Magazines

* Adjust values of ammo boxes, adjust material costs, add empty lethal/non-lethal mags, swap secfab shotgun shells with shotgun ammo boxes, add recipe for shotgun ammo boxes

* Adds fully loaded pistol mags at secfab, removes printing respective cartridges at secfab

* Adds fully loaded rifle mags at secfab, removes respective cartridges

* Adds fully loaded light rifle mags at secfab, removes respective cartridges from secfab

* Adds fully loaded speedloader to secfab, removes respective cartridges from secfab

* small id mismatch fix

* another wrong ID fix

* capitalize Ls in speedloader

* Add missing SpeedLoader recipe

* Adds fully loaded shotgun drums to secfab, removes respective shells from secfab

* add rifle ammo unlocks back in, forgot ammo unlocks affect other fabs as well

* Moves tranquilizer shells to the non-lethal ammunition research

* Account for the removal of rubbers, adds in craftable disablers

* rubber rounds don't exist, remove empty non-lethal mags to just have empty mags

* Add in WT550 mags

* Convert latheRecipes to use LayeredTextureRect instead of TextureRect

* Fix for issue, texture layering now works

* Add in missing shell uranium box art

* add shelluranium to meta.json

* Fix yml issue

* Get rid of unused single ammo printing unlocks

---------

Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-04-27 20:38:59 +10:00
PJBot
dec101465b Automatic changelog update 2024-04-27 10:36:19 +00:00
Ed
4903bc2e3d Small tomato killer tweak (#27265)
* Update miscellaneous.yml

* Update mobspawn.yml

* Update miscellaneous.yml

* Update miscellaneous.yml
2024-04-27 20:35:13 +10:00
PJBot
4d85ca5c2a Automatic changelog update 2024-04-27 10:34:41 +00:00
Errant
a62e8701cb vox oxygen toxicity, respiration changes (#26705)
* vox oxygen toxicity and related stuff

* Review

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-27 20:33:35 +10:00
PJBot
670ad3d962 Automatic changelog update 2024-04-27 10:25:05 +00:00
eoineoineoin
b8a8d6f8fc Add tooltips to artifact analyzer UI (#27393)
Add tooltips to indicate why "Extract" button is disabled.

Co-authored-by: Eoin Mcloughlin <helloworld@eoinrul.es>
2024-04-27 20:25:02 +10:00
Łukasz Mędrek
1861ae8e2b fix: localisation keys in random content books (#27390)
Fixes #27327
2024-04-27 20:23:55 +10:00
PJBot
324cce9bff Automatic changelog update 2024-04-27 10:23:16 +00:00
Ps3Moira
77d7c77f59 Canes + Cane Blade for Syndicate Librarians (#25873)
* Cane + Cane Blade

* Add - type: ContainerContainer

* Add another - type: ContainerContainer

* Fix and add proper ContainerContainer component

* Add UserInterface component

* Remove Space

* Stat Changes

* review

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-27 20:22:10 +10:00
nao fujiwara
35885345c2 tweaked the old dress sprite (#27391)
# made the waistband position consistent when rotating
2024-04-27 12:57:35 +03:00
Ed
6174713383 Merge remote-tracking branch 'refs/remotes/upstream/master' into ed-27-04-2024-displacement-upstream
# Conflicts:
#	Resources/Prototypes/Entities/Mobs/Customization/Markings/human_hair.yml
2024-04-27 10:45:35 +03:00
Ed
1840003e1c update cave wall to high format (#113)
* high cave wall

* some minor fixes

* Update cave-arena.yml

* Update natural.yml
2024-04-27 10:02:59 +03:00
PJBot
de85e6d518 Automatic changelog update 2024-04-27 06:31:35 +00:00
Łukasz Mędrek
8442a9142c fix: deconstruct verb on undeconstructables (#27387)
Some of prototypes don't specify their deconstructTarget node, which
made them show the deconstruct verb as deconstructTarget is set to
"start" node by default. This patch makes attempt to check if is it even
possible from current construction node to reach specified
deconstructTarget.

Fixes #27330
2024-04-27 16:30:29 +10:00
metalgearsloth
5ec5e5ab89 Fix lint (#27388) 2024-04-27 16:30:13 +10:00
ShadowCommander
6eb681958b Fix prying error when opening locked airlocks (#27386)
It would try to pry the door and fail to resolve a prying component on the entity trying to open the door.
2024-04-27 16:28:17 +10:00
metalgearsloth
92f14648ac Update submodule to 220.2.0 (#27385) 2024-04-27 16:07:26 +10:00
Errant
257b04d277 Vox sprite rework (#26985)
weh
2024-04-27 16:04:51 +10:00
Pieter-Jan Briers
2f7d0dedbd Displacement map prototype (#26709)
Requires https://github.com/space-wizards/RobustToolbox/pull/5023

This uses the new engine features (above) to add a displacement map shader. This allows deforming a sprite based on another sprite.

Primary use case is automatically adapting human clothing sprites to different species, something we want to make species like Vox a reality.

A basic example of wiring this up with Vox has been added. The system is however incredibly simple and **will** need more work by a content developer to select and toggle displacement maps when appropriate. I am leaving that to somebody else. For example right now the displacement map is applied even if a species already has custom-fit sprites for a piece of clothing, such as the grey jumpsuit for Vox.

Basic Aseprite plugins to help with authoring displacement maps have also been made.
2024-04-27 16:03:58 +10:00
PJBot
b4212a08f4 Automatic changelog update 2024-04-27 05:59:15 +00:00
Vigers Ray
36abf1d9ba Fix stupid NPC. (#26868)
* init commit

* Review

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-27 15:58:09 +10:00
PJBot
f898e72e57 Automatic changelog update 2024-04-27 05:48:44 +00:00
Nemanja
0215292baa welding gas mask (#27108)
* welding gas mask

* eek
2024-04-27 15:47:38 +10:00
Vyacheslav Kovalevsky
87cd1bb0ef add cancer mouse for real (#26768)
* cancer mouse

* minor tweaks

* less radioactive

* less common

* i forgor

* even more rare
2024-04-27 15:46:50 +10:00
vorkathbruh
defb8dd941 Adjusts price of SWAT crate (#27365)
Adjusts price of SWAT crate in cargo_security.yml from 5500 to 7500.
2024-04-27 15:44:59 +10:00
PJBot
bebcc70c7d Automatic changelog update 2024-04-27 05:14:19 +00:00
Tayrtahn
55177fc388 Hide disposal unit "Jump inside" verb for mobs that won't fit (#27367)
Hide "Jump inside" verb showing for mobs that won't fit
2024-04-27 15:13:39 +10:00
DrSmugleaf
46d6bf18a8 Add test for failing and then successfully starting a round (#27375)
* Add test for failing and then successfully starting nukeops preset

* Make test independent from nukeops

* Fix nullable error
2024-04-27 15:13:24 +10:00
Ty Ashley
7d4d66887b Persist Agent ID Job Icon between UI loads (#27379)
Modified the Agent ID Card to persist the selected Job Icon between UI loads
2024-04-27 15:13:12 +10:00
metalgearsloth
cc2fa6f57e Remove redundant HasUi (#27381)
Doesn't fix anything but still.
2024-04-27 15:08:50 +10:00
metalgearsloth
1dd0e0718c Update submodule to 220.1.0 (#27380) 2024-04-27 12:35:18 +10:00
PJBot
18e27342d1 Automatic changelog update 2024-04-26 22:59:31 +00:00
Pgriha
ef7d85d285 More characters slots! (#27361)
Add more character slots
2024-04-26 18:58:25 -04:00
Froffy025
0601075e79 enTranslationHelp (#115)
* enTranslationHelp

* Update tiles.ftl

* Update human-facial-hair.ftl
2024-04-26 23:40:11 +03:00
PJBot
012857331b Automatic changelog update 2024-04-26 18:52:32 +00:00
nao fujiwara
c6d935497c spooky dress and hairstyle (#27333)
* first draft loooong hair

* *added the old dress item *added old dress to the theatrical performances create

* updated spooky long hair name

* fixed an oopsie made when updating item names
2024-04-26 12:51:26 -06:00
PJBot
a04d143c2c Automatic changelog update 2024-04-26 13:07:49 +00:00
Mr. 27
50fb91bd18 monkey reinforcement teleporters can now select between kobold or monkey with a verb (#25982)
* inital

* Update animals.yml

* Update animals.yml

* Update Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>

* Update Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>

* Update Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>

* Update Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>

* Update Content.Server/Ghost/Roles/Components/GhostRoleMobSpawnerComponent.cs

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>

* selecting different role will change the description and name

* fix name

* gargh

* the review

Hello

* e

---------

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
2024-04-26 15:06:43 +02:00
PJBot
36084d9712 Automatic changelog update 2024-04-26 13:03:14 +00:00
DrSmugleaf
413d69e71f Fix the game giving up forever when not being able to start a preset (#27359) 2024-04-26 23:02:08 +10:00
metalgearsloth
30b74027fb Fix RD suffix (#27358) 2024-04-26 22:58:24 +10:00
metalgearsloth
394c325246 Fix PAI BUI (#27357) 2024-04-26 22:45:38 +10:00
lzk
3bed1ddc48 Add morgue access door (#26852)
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-26 22:45:30 +10:00
PJBot
053ec6a309 Automatic changelog update 2024-04-26 12:41:02 +00:00
wafehling
8febdc5fc4 Added hotkey and controller to re-open end of round scoreboard (#25884)
* Added keybind for scoreboard, starting work

* Fixed the window appearing

* Added loc text

* Updated namespace for ScoreboardUIController.cs

* Switched to UISystemDependency

"- UIControllers can use [Dependency] as normal for IoC services and other controllers, but must use [UISystemDependency] for entity systems, which may be null as controllers exist before entity systems do." Jezithyr — 10/12/2022 1:20 PM

* Reverted back to functional state

* Replace with UISystemDependency

* Move RoundEndSummaryWindow to ScoreboardUIController

* Convert to EntitySystem

* Clean up command bind

* Move to RoundEnd directory

* Remove Nukeops rule when no nukies

* Cleanup

* Change to toggle hotkey

* Cleanup

* Revert "Remove Nukeops rule when no nukies"

This reverts commit 5d4bbca09f45110b24a674d59b505be87b602b67.

* Cleanup

* Make the Toggle hotkey work in lobby

* Fix error

---------

Co-authored-by: SlamBamActionman <slambamactionman@gmail.com>
Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>
2024-04-26 14:39:56 +02:00
Redfire1331
080b1b1e0c Added Chopsticks (#27298)
* added chopstick sprites

* Create chopsticks.yml

* added chopstick yml

* hopfully it acts like a forke

* added chopsticks to dinnerware vendor

* uncapitalized the name

* Update Resources/Prototypes/Entities/Objects/Misc/chopsticks.yml

Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com>

* made the chopsticks icon a reasonable size

* added chopsticks to chang vendor

* made paired chopsticks you can break apart

* added them to vendors

---------

Co-authored-by: redfire1331 <Redfire1331@users.noreply.github.com>
Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com>
2024-04-26 22:39:32 +10:00
metalgearsloth
e1a5247770 Fix magic mirror prediction (#27356) 2024-04-26 22:37:09 +10:00
PJBot
11227c754c Automatic changelog update 2024-04-26 12:32:56 +00:00
WarMechanic
498109a833 fix wieldable guns not being able to cycle inhand (#27307)
* Add UnwieldOverride variable that overrides unwielding inhand to enable other interactions

* Give LMGs UnwieldOverride

* logically inverted UnwieldOverride to UnwieldOnUse

* fixed typo
2024-04-26 08:31:50 -04:00
PJBot
80bbf19f95 Automatic changelog update 2024-04-26 12:18:31 +00:00
DrSmugleaf
adce579370 Fix mobs not being able to pry doors by just left clicking on them (#27349) 2024-04-26 14:17:25 +02:00
metalgearsloth
13c6537842 Fix network configurator memory leaking (#27346)
* Fix network configurator memory leaking

Doesn't dispose this window.

* Fix the other part
2024-04-26 20:36:57 +10:00
Plykiya
35edea1c96 Fixes blank syndicate uplink UI (#27344)
Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-04-26 20:29:56 +10:00
metalgearsloth
37e03e0d29 Update submodule to 220.0.0 (#27338) 2024-04-26 18:22:23 +10:00
PJBot
934c5089a9 Automatic changelog update 2024-04-26 08:17:30 +00:00
metalgearsloth
5896e68752 Content update for UI prediction (#27214)
* Content update for UI refactor

* Big update

* Sharing

* Remaining content updates

* First big update

* Prototype updates

* AUGH

* Fix UI comp ref

* Cleanup

- Fix predicted message, fix item slots, fix interaction range check.

* Fix regressions

* Make this predictive

idk why it wasn't.

* Fix slime merge

* Merge conflict

* Fix merge
2024-04-26 18:16:24 +10:00
Ed
1f9f88883c Content (#110)
* Add many test walls

* minor bug fix

* fix torch

* add wallmount variation

* final wood wall!

* great sprite clearing + locales

* fixes

* Update bonfire.yml

* Update wallmount_torch.yml

* Update cave-arena.yml
2024-04-26 11:09:38 +03:00
PJBot
32b81de8c5 Automatic changelog update 2024-04-26 08:02:27 +00:00
Boaz1111
8af23749a1 Cluster med refactor + un-abandoning of surgery room (#27293)
* done

* cryo tweaks

* fixes error
2024-04-26 02:01:21 -06:00
IProduceWidgets
290a984c90 Oasis small tweaks (#27335)
do the easy reviews
2024-04-26 02:01:07 -06:00
DrSmugleaf
c122fdf183 Move job info changing methods for id cards to shared (#27337)
* Move job info changing methods for id cards to shared

* Revert "Move job info changing methods for id cards to shared"

This reverts commit 95cbc46b2d1934fa7bf5c72d7d3de9f9168992a1.

* Reapply changes
2024-04-26 18:00:16 +10:00
metalgearsloth
d745a788ea Fix UseDelay issues (#27336)
* Fix UseDelay issues

- Fix it not predicting properly by deep-copying the classes (realistically they should be structs).
- Fix the `z` path not applying UseDelay similarly to the `e` path.

* click
2024-04-26 17:58:06 +10:00
PJBot
fe67634397 Automatic changelog update 2024-04-26 07:49:21 +00:00
FungiFellow
e26662b545 Quiver Crafting Recipe (#27198)
* Update quiver.yml

* Create quiver.yml

* Update clothing.yml

* Update pneumatic_cannon.yml

* Update pneumatic_cannon.yml

* Update pneumatic_cannon.yml

* Update pneumatic_cannon.yml
2024-04-26 17:48:15 +10:00
PJBot
abc46f171c Automatic changelog update 2024-04-26 07:48:07 +00:00
IlyaElDunaev
3847a298c1 Treatment of blood loss in the Rat King (#26887)
Bloodloss-RatKing
2024-04-26 17:47:01 +10:00
PJBot
d578d293df Automatic changelog update 2024-04-26 07:45:46 +00:00
FungiFellow
9b63bb672f Whitelisted Sec Webbing (#27303)
* Whitelisted Sec / Merc Webbing

* Update belts.yml

* Misplaced Components fixed

* Trying to fix mapped fills

* Update belts.yml

* Update belts.yml

* Removed an Empty line

* Update belts.yml
2024-04-26 17:44:40 +10:00
PJBot
1dca65defd Automatic changelog update 2024-04-26 07:35:26 +00:00
SkaldetSkaeg
9378688ffc No echo from handheld radio (#27046)
I found the echo from my own radio very annoying.
2024-04-26 17:34:20 +10:00
Leon Friedrich
0ae942101a Fix client-side replay error (#27332) 2024-04-26 17:30:03 +10:00
Ed
7bf0ddbaa8 Merge pull request #111 from crystallpunk-14/ed-26-04-2024-upstream
26.04.2024 Upstream
2024-04-26 09:25:25 +03:00
Nemanja
735eeefa03 Migrate out rubber bullets/mags (#27329) 2024-04-26 14:22:49 +10:00
PJBot
de965416bd Automatic changelog update 2024-04-26 02:26:58 +00:00
Tayrtahn
b292905216 Expand UseDelay to support multiple delays per entity; fix bible healing and bag pickup (#27234)
* Upgraded UseDelay to support multiple delays per entity

* Implement secondary delay for bibles.
Also some improvements to make it work nicely.

* Documentation is good

* Reserve the previous change; now Storage uses the special ID and Bible uses the default.

* .0

* Added VV support to UseDelayInfo

* Serialize better

* No register, just setlength
2024-04-25 22:25:52 -04:00
PJBot
0aee198adf Automatic changelog update 2024-04-26 00:27:03 +00:00
Nemanja
a0b3a6b679 fix antag bugs (#27319)
* fix antag bugs

* Update NukeopsRuleComponent.cs
2024-04-25 17:25:57 -07:00
PJBot
281e5fa448 Automatic changelog update 2024-04-25 23:19:46 +00:00
cool dolphin
4f056672f9 Glasses in loadouts (#27286)
* loadouts now have aaall the glasses

* cheap sunglasses dont exist at all

* empty commit to rerun tests, there's no way i fucked something up
2024-04-26 01:18:39 +02:00
Ed
057556b605 Merge remote-tracking branch 'space-station-14/master' into ed-26-04-2024-upstream
# Conflicts:
#	Content.IntegrationTests/Tests/Station/EvacShuttleTest.cs
2024-04-26 00:33:04 +03:00
ShadowCommander
cf45005471 Add command to toggle ghost visibility on the client (#27314)
* Add command to toggle ghost visibility on the client

* Fix description

* Fix index of arg parsing

* Allow setting GhostVisibility directly
2024-04-25 18:26:21 +02:00
SoulFN
960a50c0ff Buff revenant structural damage (#27309)
* 15 > 50

* update

50 >> 60
2024-04-25 21:02:25 +10:00
PJBot
e450fadbaa Automatic changelog update 2024-04-25 02:20:23 +00:00
beck-thompson
d3b1178428 Radio jammer update! (#25912)
* Added selectable power level to radio jammer

* Cleaned up OnGetVerb

* Settings are now stored in the .yml file. Simplified stuff a lot!

* Minor fixes!

* Small little baby fix :)

* Added the power level switch to the examine menu and also removed the ftl file as it was in the incorrect location.

* Minor code cleanup

* Changed byte -> int

* Update sprite

* Fixed licence

* Added power LED that changes if the jammer is on low power.

* Removed tabs

* Changed github link to the commit

* Changed all the RemComp to RemComDeferred

* Moved NetworkedComponent to shared

* Changed radio jammer textures back with minor edits

* Added a space because it was annoying me

* Jammer now updates range for suit sensors properly! Thanks nikthechampiongr :)

* Removed useless comment

* Cleaned up code that updates the range of tracking devices.

* Fixed client namespace and removed newline

* Cleaned up ChangeLEDState and ChangeChargeLevel.

* Added comments

* Read only

* Fixed another comment

* Locked in

* Made server inherit shared

* Update Content.Shared/Radio/EntitySystems/SharedJammerSystem.cs

* Update Content.Shared/Radio/EntitySystems/SharedJammerSystem.cs

* review fixes

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-25 12:19:16 +10:00
Leon Friedrich
6d16d6b1c9 Fix DoAfter attempt event null error (#27280)
* Fix DoAfter attempt event null error

* A
2024-04-25 11:54:25 +10:00
Nemanja
161fd6c83c Mega Antag Refactor (#25786)
* Mega Antag Refactor

* last minute delta save

* more workshopping

* more shit

* ok tested this for once

* okkkkk sure

* generic delays for starting rules

* well darn

* nukies partially

* ouagh

* ballin' faded and smonkin wed

* obliterated the diff

* Spread my arms and soak up congratulations

* I've got plenty of love, but nothing to show for it

* but there’s too much sunlight
Shining on my laptop monitor, so I
Can’t see anything with any amount of clarity

* ok this junk

* OOK!

* fubar

* most of sloth's review

* oh boy

* eek

* hell yea!

* ASDFJASDJFvsakcvjkzjnhhhyh
2024-04-25 11:31:45 +10:00
Nemanja
771661f478 fix analysis console bias button for real (#27299)
fix bias button for real
2024-04-25 11:26:55 +10:00
metalgearsloth
f6ac494ad3 Fix .ftl keys (#27289)
Required for https://github.com/space-wizards/RobustToolbox/pull/4885 to not kill content
2024-04-24 21:19:17 -04:00
PJBot
eb648dd0eb Automatic changelog update 2024-04-24 21:28:40 +00:00
pigeonpeas
ef0a4d64c8 Add a trash bag to the advanced cleaning borg module. (#27226)
add the trash bag

puts the trash bag in the advanced cleaning module
2024-04-25 00:27:34 +03:00
deltanedas
d797e3753f saltern bar stool (#27263)
saltern stool

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-04-24 13:40:54 -06:00
Ed
045c81b3c4 Merge pull request #108 from crystallpunk-14/ed-24-04-2024-workshop-ports
Jaraten walls and wallmounts
2024-04-24 20:45:21 +03:00
Ed
8ef8cf6098 add wallmounts things 2024-04-24 20:28:25 +03:00
metalgearsloth
17160fad83 Update submodule to 219.2.0 (#27294) 2024-04-25 00:35:56 +10:00
Leon Friedrich
8aabb1c2e5 Content changes & tests for engine prototype validation PR (#27188)
* Content changes & tests for engine prototype validation PR

* A
2024-04-25 00:27:13 +10:00
Pieter-Jan Briers
7b90c08a2c Various item status fixes/tweaks (#27267)
* Always display item status panel fully

Initial feedback from the UI changes seems to be that a lot of people go "why is there empty space" so let's fix that.

* Fix item status middle hand being on the wrong side

I think I switched this around when fixing the left/right being inverted in the UI code.

* Minor status panel UI tweaks

Bottom-align contents now that the panel itself doesn't dynamically expand, prevent weird gaps.

Clip contents for panel

* Fix clipping on implanters and network configurators.

Made them take less space. For implanters the name has to be cut off, which I did by adding a new ClipControl to achieve that in rich text.

* Update visibility of item status panels based on whether you have hands at all.

This avoids UI for borgs looking silly.

Added a new "HandUILocation" enum that doesn't have middle hands to avoid confusion in UI code.

* Use BulletRender for laser guns too.

Provides all the benefits like fixing layout overflow and allowing multi-line stuff. Looks great now.

This involved generalizing BulletRender a bit so it can be used for not-just-bullets.

* Fix geiger word wrapping if you're really fucked
2024-04-25 00:01:31 +10:00
PJBot
38f490e5eb Automatic changelog update 2024-04-24 13:45:03 +00:00
FungiFellow
5fa424a43b Add Truncheon to Secbelt Whitelist (#27281)
* Add Truncheon to Secbelt Whitelist

* Update belts.yml

* Added Truncehon Tag in Tags.yml

* Update security.yml

* Update security.yml
2024-04-24 16:43:56 +03:00
PJBot
7f6f9c1209 Automatic changelog update 2024-04-24 13:22:36 +00:00
Alzore
4290d5f13e Make the cargo telepad T2 civilian (#26270)
therearetwowaystodothis
2024-04-24 23:21:28 +10:00
Tayrtahn
480d26aba6 Fix climbing and bonking simultaneously (#27268)
* Properly network ClumsyComponent

* Fix being able to climb and bonk at the same time.
Also properly subscribe to AttemptClimbEvent by-ref.

* Update Content.Shared/Interaction/Components/ClumsyComponent.cs
2024-04-24 23:02:43 +10:00
Ed
b0a11462d6 cave wall sprite fix 2024-04-24 11:39:05 +03:00
Ed
6307c1b1b5 add walls 2024-04-24 11:28:25 +03:00
Leon Friedrich
91aa16f08a Add NukeOps Test (#27207)
* Add NukeOps Test

* Update EvacShuttleTest to also check mapinit

* Update RuleMaxTimeRestartTest

* Fix cvar cleanup

* A

* Revert some changes

* comments

* Add MappingTests

* Finally fix the test

* A
2024-04-24 15:38:43 +10:00
Nemanja
49f1c8b197 fix analysis console not saving bias button state (#27275) 2024-04-24 01:35:16 -04:00
PJBot
829b453e3c Automatic changelog update 2024-04-24 02:43:41 +00:00
Plykiya
14bc595442 Do-afters belonging to other players are now shaded (#27273)
Make do-afters belonging to other players shaded

Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-04-23 19:42:34 -07:00
Flareguy
10ad53df72 Revert "Maints Exit Sign" (#27271)
Revert "Maints Exit Sign (#26831)"

This reverts commit 905102064c.
2024-04-23 20:40:26 +02:00
PJBot
0c851d256d Automatic changelog update 2024-04-23 12:08:18 +00:00
Nemanja
1bfc63c546 fix cargo teleporter (#27255)
* fix cargo teleporter

* don't delete orders

* basado
2024-04-23 22:07:12 +10:00
PJBot
8117131c91 Automatic changelog update 2024-04-23 11:35:15 +00:00
pigeonpeas
c129bb177c Allow the purchase of emitters from cargo. (#27229)
add emitter crates back to cargo + changes the contents of an emittercrate from emitter to emitterflatpack

👍
2024-04-23 21:34:09 +10:00
PJBot
716cdcbdf8 Automatic changelog update 2024-04-23 11:32:54 +00:00
brainfood1183
905102064c Maints Exit Sign (#26831)
* Maints Exit Sign

* change description

* id, sprites changed from maints to exit
prototype now has an unshaded layer so it can be seen in the dark.
2024-04-23 21:31:48 +10:00
PJBot
401911b734 Automatic changelog update 2024-04-23 11:31:07 +00:00
Whisper
eee056eaf0 lower max firestacks to 10, refactor flammable (#27159)
* lower max firestacks to 10, refactor flammable

* fix

* uncap fire stack damage, lower fire stack damage
2024-04-23 21:30:01 +10:00
PJBot
2f0c02ef35 Automatic changelog update 2024-04-23 11:26:04 +00:00
Ghagliiarghii
88b56efba1 Increase availibility of combat knives to security (#27224)
* Increase availibility of combat knives to security

* whitelisted combatknife in secbelt for Diona

* Revert SecDrobe change for MGS
2024-04-23 21:24:58 +10:00
PJBot
31b9f98e6d Automatic changelog update 2024-04-23 08:58:15 +00:00
Skye
32c1f8f8cd Fix: Suit Sensors Vitals (#27259)
Vitals now functions correctly
2024-04-23 10:57:09 +02:00
PJBot
c4a6bcca5c Automatic changelog update 2024-04-23 08:49:33 +00:00
Tyzemol
0e2f5d6bf7 Fix slime storage issue (#27260)
fix_slime_storage
2024-04-23 10:48:26 +02:00
Leon Friedrich
06a5e00c99 Update engine to v219.1.3 (#27257) 2024-04-23 14:28:09 +10:00
PJBot
ee0f63d273 Automatic changelog update 2024-04-22 22:47:28 +00:00
Tayrtahn
8eecd9cc2d Prevent ghosts from triggering examine artifact triggers (#27249) 2024-04-22 18:46:22 -04:00
Ed
e888747d0c Merge pull request #107 from crystallpunk-14/ed-22-04-2024-weapon-update
Weapon update
2024-04-22 23:55:52 +03:00
Ed
8ba56847bb add crossBOLT 2024-04-22 22:01:47 +03:00
Ed
39f64dea73 added light crossbow 2024-04-22 21:46:11 +03:00
Ed
43384c1125 weapon rebalance + weapons equipping on move 2024-04-22 20:36:54 +03:00
Ed
08960fb197 Merge pull request #106 from crystallpunk-14/21-04-2024-cleaning-up
Upstream Sync
2024-04-22 20:22:28 +03:00
Ed
23df20c0fe Update EvacShuttleTest.cs 2024-04-22 20:10:01 +03:00
Ed
1210e1da86 Revert "return maps prototypes"
This reverts commit 894c10c409.
2024-04-22 20:05:14 +03:00
Ed
f94997fe5f Revert "Update PostMapInitTest.cs"
This reverts commit 32bf32d2dc.
2024-04-22 20:05:05 +03:00
Ed
6185ddc64c Revert "fix"
This reverts commit 132cc73fb7.
2024-04-22 20:05:01 +03:00
Ed
132cc73fb7 fix 2024-04-22 18:32:26 +03:00
Ed
32bf32d2dc Update PostMapInitTest.cs 2024-04-22 18:12:21 +03:00
Ed
894c10c409 return maps prototypes 2024-04-22 18:09:21 +03:00
lzk
5b0c3ecf73 Little analysis console rearrangement (#27244) 2024-04-22 10:00:13 -04:00
PJBot
8bc2ee81dd Automatic changelog update 2024-04-22 12:19:34 +00:00
FungiFellow
32a90120eb Syndi-Cat Tweaks (#27222)
* Syndicat Price 10 -> 6

* Update animals.yml

* Update animals.yml

* Update uplink_catalog.yml

* Update uplink_catalog.yml

* Update animals.yml
2024-04-22 15:18:28 +03:00
Ed
f972f3129d update debug walls 2024-04-22 13:37:44 +03:00
Kara
85c6383cc0 Minor slime fix (#27237) 2024-04-22 03:18:36 -07:00
PJBot
289bbc70d7 Automatic changelog update 2024-04-22 10:04:08 +00:00
Just-a-Unity-Dev
fd0ca42c58 General slime improvements (#23425)
* General slime improvements

* Finish morphing

* oops 2x2 not 3x3

* actually lets ball - 2x3 inventory

* Last two things on the todo list

* .\RobustToolbox\

* JUST COMPILE

* fix tests 2.0

* fix tests 3.0

* Do reviews

* minor change

* guideboob

* more

---------

Co-authored-by: Kara <lunarautomaton6@gmail.com>
2024-04-22 03:03:03 -07:00
PJBot
af516cff61 Automatic changelog update 2024-04-22 09:00:00 +00:00
Terraspark4941
c5ab839b2c Engineering guidebook update (#26851)
* RTG page update

* old commits from #22272

* Small fixes over most pages

* TEG tweaks

* Fixed a thing in airlock security

* fixed an italics tag

* singularity page now includes tesla

* Added a burn chamber to TEG page

* Prettyprinted TEG page, fixed some more issues with details

* Moved ONE singular comma

* Change Singularity page heading to include tesla

* Singularity page pretty printing + fixes

* TIL its [italic] NOT [italics]

* RTG Prettyprinting

* Access Config Prettyprinting + Netconfig tweak

* Atmospherics prettyprinting

* Construction keybind fix

* Apply suggestions from code review

---------

Co-authored-by: Kara <lunarautomaton6@gmail.com>
2024-04-22 01:58:54 -07:00
PJBot
52204dfa35 Automatic changelog update 2024-04-22 08:46:44 +00:00
potato1234_x
e2b260d894 Psicodine, Mannitol, Lipolicide and Happiness (#27134)
* reagents

* Update Resources/Locale/en-US/reagents/meta/narcotics.ftl

---------

Co-authored-by: Kara <lunarautomaton6@gmail.com>
2024-04-22 01:45:38 -07:00
PJBot
35ac720d19 Automatic changelog update 2024-04-22 08:45:19 +00:00
Weax
b5bcf86b74 Make CLF3 reaction require heating first. (#27187)
* heat your bombs

* Removing comment
2024-04-22 01:44:14 -07:00
PJBot
bffad8053a Automatic changelog update 2024-04-22 08:43:33 +00:00
deltanedas
fcf5057b61 make fire spreading scale with mass (#27202)
* make fire spreading scale with mass

* realer

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-04-22 01:42:26 -07:00
DrSmugleaf
b0e6ff6779 Add events for custom action target validation (#27230) 2024-04-22 01:39:50 -07:00
keronshb
210e6f6444 Polymorphs spawn using the parents world rotation (#27223)
changes polymorph spawn to use angle
2024-04-22 01:39:07 -07:00
DrSmugleaf
81f2dc7cf9 Add SharedPopupSystem.PopupClient for cursor and coordinates (#27231) 2024-04-22 13:57:13 +10:00
Pieter-Jan Briers
6b1866625c Make sterile masks a tiny item (#27213)
This minorly annoyed me because breath masks are tiny too, so if I swapped them I may run out of inventory space.
2024-04-22 13:51:29 +10:00
Wrexbe (Josh)
c93052c755 Escape markup for in-game chat, and labeler (#26359)
* Escape markup for in-game chat, and labeler

* different way

* remove a using

---------

Co-authored-by: wrexbe <wrexbe@protonmail.com>
2024-04-21 20:37:50 -04:00
beck-thompson
877ccd6e8f Fixed grammar when drinking empty drink (#27218)
Fix
2024-04-21 14:57:39 -04:00
Ed
f947f97878 remove oasis 2024-04-21 21:08:56 +03:00
Ed
a899122d1b Merge remote-tracking branch 'space-station-14/master' into 21-04-2024-cleaning-up
# Conflicts:
#	Content.IntegrationTests/Tests/PostMapInitTest.cs
#	Resources/Prototypes/Maps/Pools/default.yml
#	Resources/Prototypes/Maps/europa.yml
#	Resources/Prototypes/Recipes/Lathes/electronics.yml
#	Resources/Textures/Interface/Nano/item_status_left.svg.96dpi.png
#	Resources/Textures/Interface/Nano/item_status_middle.svg.96dpi.png
#	Resources/Textures/Interface/Nano/item_status_right.svg.96dpi.png
2024-04-21 20:54:50 +03:00
Ed
71fae31507 Merge pull request #104 from crystallpunk-14/21-04-2024-deathmatch-gamemode
Deathmatch gamemode
2024-04-21 20:16:34 +03:00
Ed
4609079680 balance tweaks 2024-04-21 19:45:00 +03:00
PJBot
541e87395a Automatic changelog update 2024-04-21 16:10:32 +00:00
Hannah Giovanna Dawson
f059714a75 SS14-26480 Roll Traversal Distorter into regular Artifact Analyzers (#26545)
* SS14-26480 Roll Traversal Distorter into regular Artifact Analyzers

Bit of a grab-bag of cleanup of Xenoarchaeology prompted by #26480.

1. Traversal distortion biases are now "up" and "down" instead of "in" and "out".
2. Node generation has been tidied up to make it a little clearer how it works.
3. Traversal Distorters have been removed from the game along with their board.
4. Traversal distortion is now done by the artifact analyzers by default.
5. Some loc strings have been made clearer.
6. The Abnormal Artifact Manipulation tech has been made slightly cheaper.
7. The aformentioned tech is now localized as Artifact Recycling, given all it does is unlock the crusher.
8. The Xenoarchaeology guidebook entry has been given a bit of a rewrite, putting all information into
one page and making sure to cover the basics that otherwise would require someone typing "Liltenhead
artifact tutorial" into Youtube.

* Fix references to deleted guidebook entry

* Add fancy button to console because @EmoGarbage404 asked me to

* migration comprete

* Fixed a goober comment

* maint fails to resolve conflicts: more at 11

* Resolve PR comments

* Make UI nice

---------

Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
2024-04-21 12:09:26 -04:00
Ed
faff0d203a Update cave-arena.yml 2024-04-21 18:31:56 +03:00
Ed
0ca5d5110d Update cave-arena.yml 2024-04-21 18:28:32 +03:00
K-Dynamic
e009a80a8c Removed CC and recall reference in pallet descriptions (#27209)
cleaned pallet descriptions
2024-04-21 11:21:36 -04:00
Ed
2c0df7fc72 Update PostMapInitTest.cs 2024-04-21 18:07:55 +03:00
Tayrtahn
50631f430d Add clothing equipped/unequipped events (#27155)
* Added ClothingGotEquipped/ClothingGotUnequipped events

* Better version

* Implemented in a few places

* More implementations

* Add ClothingDidEquipped/ClothingDidUnequipped events
2024-04-21 11:00:50 -04:00
Ed
b092f190f6 cp14 2024-04-21 17:55:18 +03:00
Ed
b701804836 Merge branch '21-04-2024-deathmatch-gamemode' of https://github.com/crystallpunk-14/crystall-punk-14 into 21-04-2024-deathmatch-gamemode 2024-04-21 17:33:13 +03:00
Ed
49b39e9535 fixes 2024-04-21 17:32:52 +03:00
Ed
59dc76b423 Merge branch 'master' into 21-04-2024-deathmatch-gamemode 2024-04-21 17:19:26 +03:00
Ed
ba03750394 add map and gamerule 2024-04-21 17:14:03 +03:00
Pieter-Jan Briers
84c3d225ca Buff welding supplies closet (#27212)
In SS13 this closet gives you THREE welding masks and THREE welders. Over here, sometimes it only contained a single mini welding tool.
2024-04-21 09:40:00 -04:00
Ed
cf96612a81 Merge pull request #103 from crystallpunk-14/21-04-2024-species-naming
add species name generation
2024-04-21 16:28:04 +03:00
PJBot
7c07391998 Automatic changelog update 2024-04-21 13:17:29 +00:00
Pieter-Jan Briers
58f025ba80 THE RETURN OF ITEM STATUS (#22986)
* THE RETURN OF ITEM STATUS

Item status is now inline with the hands again. You can now see item status for both hands at once.

If you have more than 2 hands, the last active hand of that side is displayed in the respective item status.

The item status for the active hand is also highlighted.

Item status has been given a new look so it looks unique and matches every UI theme.

* Shrink item status to 125px

This is going to require fixing the existing controls. Do that later.

* New bullet item status rendering

sex

* Make gun item status look just a little bit nicer.

Avoid only one or two bullets ending up on a single row of an item status.

* Delete Eris theme files

* More improvements

Fixed the fact that left/right were flipped around when assigning status panel locations. Involved renaming all the UI textures.

Redid how content margins are set from the theme. Less complex and cleaner now.

Made the item name always left-aligned, just looks better since other UI elements don't adapt anyways.

* Compact down item status text

Now it fits 3 lines of text on one line. Yay.

This is achieved by compacting RichTextLabels by reducing their line height and giving them a negative bottom margin.

* Add item status sprites for Ashen theme.

* Add status control to show beaker/bucket/jug solution/transfer volumes

Also PollingItemStatusControl I'll be using that more.

* Fix welder item status, clean up welder code

The item status control implementation was ancient and bad. That's why it was buggy.

Removed all the complex dated networking stuff for welders, we just sync the solution contents now anyways so none of that is needed anymore. This moves a buncha stuff to shared and just removes code.

Cleanup. The code was doing some really dumb stuff.

* Spray bottles show contents in item status.

* cowtools

* Fix plasmafire and clockwork themes.

Actual git gaslighting wtf.

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-21 23:16:23 +10:00
Ed
c156d09081 add comment 2024-04-21 15:46:46 +03:00
Ed
8f135d9745 localize human names 2024-04-21 15:43:26 +03:00
Ed
d342db3d65 Merge branch 'master' into 21-04-2024-species-naming 2024-04-21 15:26:41 +03:00
Ed
b2226cbe16 localized tiefling name 2024-04-21 15:25:22 +03:00
PJBot
ee4ef4b96a Automatic changelog update 2024-04-21 11:54:14 +00:00
Alzore
fb8dcfe6bf Add rainbow jumpsuit to passenger loadout. (#27211)
* Add all colored jumpsuits to passenger loadout

* onlyrainbowiguess
2024-04-21 21:53:08 +10:00
Ed
d29afc0f4c add species name generation 2024-04-21 14:42:12 +03:00
Ed
caf5ca3dc8 Merge pull request #102 from crystallpunk-14/20-04-2024-clothing-pack
Torch + aristocratic clothing set
2024-04-21 14:42:01 +03:00
Ed
fb96392077 add torch crafting 2024-04-21 13:52:22 +03:00
Júlio César Ueti
362033a0c7 Fix ghost prayer interaction (#27199)
fix ghost prayer interaction

Co-authored-by: Júlio César <j.cesarueti@yahoo.com>
2024-04-21 19:01:00 +10:00
Leon Friedrich
8b2179d0ae Update engine to v219.1.2 (#27206) 2024-04-21 19:00:23 +10:00
PJBot
9fa08fe8c2 Automatic changelog update 2024-04-21 06:53:50 +00:00
Leon Friedrich
29302ae6cd Update engine to v219.1.1 (#27201) 2024-04-21 16:52:45 +10:00
PJBot
0526384d16 Automatic changelog update 2024-04-21 06:20:27 +00:00
SpeltIncorrectyl
b6d751eb70 Adds security webbing and security belts to Security Officer loadout (#27189)
* added filled security webbing

* moved sec belt to loadout

* added webbing for head of security and warden
2024-04-21 00:19:20 -06:00
KittenColony
b48d0ddefc Two-Tone lizard snouts (#27143)
snouts
2024-04-21 00:18:33 -06:00
PJBot
2b3076832f Automatic changelog update 2024-04-21 06:00:19 +00:00
IProduceWidgets
7b0b894e44 Add map Oasis (#25736)
* Add map Oasis

* integration test fix

* psych job

* 1984 an invalid component

* address reviews

* address reviews, touch ups.

* tiny feexes

* move a tree

* Actually put it in the active maps pool.

* minor tweeks

* tweek some door accesses.

* add extra lawyer, make evac the right docking arrangement.

* Address the small things, fix cryopods, make perma huge.

* Fix some small things in the new perma.

* Improve perma spacing resiliancy... maybe.

* burn the invalids

* Pray to the Sloth gods that painters arent cooked.

* rearrange some buttons

* fix fax names and add a genedrobe.

* Housekeeping

* fix some stuff I thought I already fixed

* wood benches

* Some under door tiles, a couple missing decals.

* one pipe got brokey. feexit!

* astrograsses and lathe to cargo

* N2 lockers, minor things.

* cap laser to case

* GridFill the briggle so it feels better. Some other minor things

* name the Briggle correctly
2024-04-20 23:59:12 -06:00
Ubaser
01ce407019 Update Core (#27195)
* add

* fix invalid
2024-04-20 23:58:23 -06:00
github-actions[bot]
d2fb5130c9 Update Credits (#27192)
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
2024-04-21 04:13:08 +02:00
Leon Friedrich
c4f050259d Try fix random shuttle test failures (#27186) 2024-04-21 08:03:55 +10:00
Tayrtahn
5d80e49d37 Make material arbitrage test ignore price of contained entities (#27182)
Material arbitrage test now ignores price of contained entities
2024-04-21 08:03:11 +10:00
Tayrtahn
f253067a69 Possible fix for evac shuttle test failures (#27175)
It couldn't be this easy, could it?
2024-04-21 07:55:43 +10:00
Ghagliiarghii
380ace4ef0 Fixed potential duplicate engraved lighter steal objective (#27177)
* Fixed potential duplicate engraved lighter steal objective

* Update Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>

* Implement pigeonpeas' suggestion

* Also replaced the one if the vending machine, unsure if this vending machine is used or if vended items retain their fills, but figure can't hurt

---------

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
2024-04-21 07:32:24 +10:00
Tayrtahn
1fb7393a1b Make material arbitrage test more verbose (#27180)
List entities spawned by destruction for debugging
2024-04-21 07:23:09 +10:00
Leon Friedrich
3bfd5d2c4e Un-revert #26994 (#27184) 2024-04-21 09:18:09 +12:00
ElectroJr
3a8249e5fd Un-revert #26994 2024-04-20 17:01:15 -04:00
Leon Friedrich
5982007d0e Updatte engine to v219.1.0 (#27183) 2024-04-21 08:54:59 +12:00
ElectroJr
bd63a3f9c1 Updatte engine to v219.1.0 2024-04-20 16:54:04 -04:00
Mr. 27
663542b82e belts get their equip sound (#27174)
done
2024-04-20 15:52:02 -04:00
Plykiya
6ad039d0f9 Fix for inventory and belt not opening (#27179)
Co-authored-by: Plykiya <plykiya@protonmail.com>
2024-04-20 20:24:52 +02:00
PJBot
ac7842cacd Automatic changelog update 2024-04-20 16:19:32 +00:00
nikthechampiongr
f96f92f54f Make banpanel defaults use cvars (#27168)
* Make banpanel respect CCVars. Add CCVars for default ip/hwid/use last
details checkboxes.

* Move severity handling for server/role ban to another function

* Save sawmill

* Line goofyness

---------

Co-authored-by: Vasilis <vasilis@pikachu.systems>
2024-04-20 18:18:26 +02:00
Ed
c266046cbd nuke it 2024-04-20 18:02:09 +03:00
PJBot
af939af47c Automatic changelog update 2024-04-20 14:45:16 +00:00
Whisper
c7bbaa48a4 fix burning to ash not working on all mobs (#27158) 2024-04-20 10:44:10 -04:00
K-Dynamic
b6781946df Corrected misleading protections in jumpsuit/skirt descriptions (#27160)
removed misleading protections
2024-04-20 10:08:21 -04:00
Ed
966a54fbc6 add torch 2024-04-20 16:54:03 +03:00
deltanedas
9482144a19 disable rehydration prediction (#27166)
Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-04-20 09:51:56 -04:00
Ed
f271c8cff0 add aristocratic set 2024-04-20 15:59:15 +03:00
Ed
0b587e9fb9 Merge pull request #101 from crystallpunk-14/20-04-2024-nospawn-global
barrel + CP14 prefix
2024-04-20 15:03:38 +03:00
Ed
bbbf7172a9 fixes 2024-04-20 14:54:01 +03:00
Ed
6db92d86b5 Update walls.yml 2024-04-20 14:43:27 +03:00
Ed
e98a6e17a3 Update structures.ftl 2024-04-20 14:18:22 +03:00
Ed
4763bffeac locale update 2 2024-04-20 14:16:11 +03:00
Ed
d74a33d46b locale update 2024-04-20 14:10:10 +03:00
Ed
c70b267bbb barrel update 2024-04-20 14:03:06 +03:00
Ed
c3f7ad2fae fix character preview 2024-04-20 13:26:41 +03:00
Ed
5e498f68a6 fixes 2 2024-04-20 13:01:45 +03:00
Ed
af734dc5c2 fixes 2024-04-20 12:45:25 +03:00
Ed
bb24ead3b9 Update barrel.yml 2024-04-20 12:28:33 +03:00
Ed
ca01030da1 Fucking big refactor 2024-04-20 11:51:04 +03:00
DrSmugleaf
5eae6335e1 Make remaining IPrototypes partial (#27157) 2024-04-20 17:48:38 +10:00
PJBot
ddaaadd204 Automatic changelog update 2024-04-20 06:47:07 +00:00
deathride58
396c613366 Adds the option to fit the viewport to vertical screenspace (#27061)
* Adds the option to fit your viewport to your vertical screenspace

* fixes documentation

* Removes commented-out leftover

* Hides the viewport width slider and also we dont know if the viewport width causing stretching/squishing was a bug present before but we fixed that while we were at it

* Removes commented out leftovers
2024-04-20 16:46:02 +10:00
no
5c69031d11 Admin log shuttle gibbing + Make shuttle gibbing and immovable rods drop organs and correctly put player in ghost (#27114)
* Add admin log when someone gets gibbed by a shuttle

* Make shuttle gibbing work properly again

* Fix immovable rod gibbing, no longer puts you into nullspace

* Update Content.Server/ImmovableRod/ImmovableRodSystem.cs

* Update Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-20 16:27:38 +10:00
PJBot
f395c45dd2 Automatic changelog update 2024-04-20 06:27:06 +00:00
MilenVolf
2da53d97e5 Windoors now contain proper electronics (#27133)
* Windoors now contain proper electronics

* weh
2024-04-20 16:26:00 +10:00
PJBot
de9c234e20 Automatic changelog update 2024-04-20 06:24:26 +00:00
DrSmugleaf
3c6722bd6f Move storage binds and slot click handling to shared (#27135) 2024-04-20 16:23:45 +10:00
MilenVolf
812abd33a0 Fix crates masks (#27137)
Fixes crates masks not allowing them to go under plastic flaps + crates no longer can go trough windoors.
2024-04-20 16:23:20 +10:00
Verm
58e21a8532 Add medical gloves and sterile masks to medical loadouts (#27029)
* Add medical gloves to loadouts

* Realize I don't need to duplicate them

* Re-add extra lines

* I did it wrong...

* Format it back to how it was this time for sure

* For real this time

* ...

* Add sterile masks too

* I can't spell officer apparently

* Standardize order of where gloves are

* Add Nurse Hat to doctors

* Remove duplication of gloves and masks

* Remove extra space

* Name glove protos similiar to other ones

* Remove latex gloves proto from medical (sci has it)
2024-04-20 16:22:48 +10:00
PJBot
16ed6ee81d Automatic changelog update 2024-04-20 06:22:18 +00:00
SoulFN
95c66b4f96 Glass shards damage (#26783)
* Update shards.yml

Changed glass shards damage depends on their type, each tier of glass gains 1 more damage, also changed attack rate to 1, because you cant fast swing with weapon that can hurt you

* Oops

Forgot about base shard

* Update shards.yml

Cleanup

* Update shards.yml

Changed damage on step (Attack damage + 1)
2024-04-20 16:21:12 +10:00
PJBot
238c87ce17 Automatic changelog update 2024-04-20 06:18:01 +00:00
Verm
089c9cb967 You can bless more containers with a bible (#26526)
* Made more things blessable

* Removed junk

* Remove whatever that was

* Make bowls blessable

* New mixablesolution component, converted everything to work with it

* Fix minor mishaps

* Fix extra spaces in bottle yml

* Fix last extra space, fix bottle havign the wrong solution name

* Remvoe unneeded event(I think), fix alcohol bottles not being mixable

* I missed cans
2024-04-20 16:16:55 +10:00
PJBot
c85bdef7f1 Automatic changelog update 2024-04-20 06:11:29 +00:00
UBlueberry
8eab1f499f Guidebook update for the Space Ninja (#26650)
* added ninja to Antagonists.xml

* give the space ninja some love

* by the way did you know there are now 25 fiber types? i demand this number get updated with every single PR
2024-04-20 16:10:22 +10:00
Nim
3f2e15896b Floor trap (#26314)
* trap

* without effect
2024-04-20 16:09:00 +10:00
Leon Friedrich
12bb476a2d Add evac shuttle test. (#27152)
* Add evac shuttle test.

* Fix typo in comment
2024-04-20 15:57:55 +10:00
Tayrtahn
4594700d19 Fixed debug assert while getting network state in ClothingSystem (#27153) 2024-04-20 15:54:44 +10:00
PJBot
fc7839eeba Automatic changelog update 2024-04-20 03:45:44 +00:00
slarticodefast
b22c06230c fix cryopod volume (#27148) 2024-04-19 23:44:39 -04:00
Nemanja
e5a5196b1f make filled inventory slots blank (#27150)
* blank filled slots

* Update InventoryTemplatePrototype.cs
2024-04-20 13:17:29 +10:00
metalgearsloth
ef7f0b8322 Optimise immovable rod mapinit (#27149)
Redundant getworldpos.
2024-04-20 13:07:25 +10:00
keronshb
6be204e3f4 Adds non randomized rod velocity (#27123)
* adds non randomized rod velocity

* Adds despawn suffix to despawn rod
2024-04-19 22:18:25 -04:00
PJBot
533453eb81 Automatic changelog update 2024-04-20 02:11:25 +00:00
Leon Friedrich
349f78dc80 Try fix emergency shuttle not spawning (#27144) 2024-04-20 14:10:19 +12:00
PJBot
5a5167d6cb Automatic changelog update 2024-04-20 02:07:54 +00:00
Gyrandola
fa5b93871f chili/chilly peppers sprite alignment fix & minor refactorization (#25971)
* png alignment and minor refactorization

* Update migration.yml

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-20 12:06:48 +10:00
metalgearsloth
b2b1926ecc More storage tweaks (#25970)
- Fix some prediction stuff.
- Fix some jank.
- UseDelay.
- Cap.
2024-04-20 11:51:16 +10:00
PJBot
7000974319 Automatic changelog update 2024-04-20 01:16:03 +00:00
osjarw
acb112b054 Wallmount substations can once again be created (#27138)
* Wallmount substation once again obtainable

* Fill mapped wallmount substations with components
2024-04-20 11:14:57 +10:00
PJBot
ce5934bd67 Automatic changelog update 2024-04-20 01:08:16 +00:00
dffdff2423
cff8083650 Disable Communication Console Announcement Button for Too Long Messages. (#27145)
Disable comms console announce for long messages

Disable the "announce" button on the communications console for messages
above the cap. I did not touch broadcasting because I could not identify
an easy way to check the maximum length for it.
2024-04-20 11:07:10 +10:00
Aexxie
fa9abbaff4 No More Bartender Incendiaries on Meta (#27142)
deleted bartender's incend
2024-04-20 11:06:21 +10:00
pigeonpeas
aa0fc72b1a Add new jukebox song. (#27074)
add song to jukebox

for funsies!
2024-04-19 19:41:32 -04:00
PJBot
610e73543c Automatic changelog update 2024-04-19 23:23:42 +00:00
superjj18
fdf04c2779 Reduced Pneumatic Cannon inventory space by 75%, removed cannon blacklist (#26878)
Reduced Pneumatic Cannon inventory space by 75%, removed cannon whitelist.
2024-04-19 19:22:36 -04:00
PJBot
c6f8cf080a Automatic changelog update 2024-04-19 23:21:36 +00:00
Nemanja
a47c5561a9 add fuel costs back to finishing welding (#27030)
* add fuel costs back to welding

* ack

* meh

* eek!
2024-04-19 19:20:30 -04:00
ElectroJr
7aa1818823 Update EmergencyShuttleSystem.cs 2024-04-19 19:00:55 -04:00
ElectroJr
6373454242 Fix emergency shuttle initialization 2024-04-19 18:57:12 -04:00
Tayrtahn
299da35c87 Make YAML Linter validate server/client-only components (#26809)
* YAML Linter now validates invalid fields in server-only and client-only components

* Update to change in engine PR

* Use reflection manager to get the lists of client/server assemblies.

Also made it use a hashset on type instead of the previous code.

* I'm dumb my bad.

* Fix 2 errors that snuck through, showing why we need this.

---------

Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
2024-04-19 13:28:33 -04:00
PJBot
5b62724de0 Automatic changelog update 2024-04-19 05:51:16 +00:00
deltanedas
33abb6bb3f webedit ops (#27131) 2024-04-19 15:50:34 +10:00
shamp
1bfcc062f2 Stunprod rework (#25922)
stunprod
2024-04-19 15:50:10 +10:00
PJBot
8703a30647 Automatic changelog update 2024-04-19 05:40:54 +00:00
deltanedas
350843d2c0 add dirty calls to mask system (#27128)
* add dirty calls to mask system

* among

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-04-19 15:40:23 +10:00
SlamBamActionman
7aa4beede6 Fix lizard snouts disappearing when wearing masks (#25716)
* fixes it

* Snout fix

* Partway commit

* Partway commit

* Update masks and helmets to use the new system
2024-04-19 15:39:47 +10:00
no
94f296f9d6 "make thief" admin action: fix missing icon (#27119) 2024-04-19 15:27:36 +10:00
Golinth
5146853484 Fix Mindshield positioning (#27120)
fixed-ops

Im sure there is a more elegant way of fixing this, but this way requires no code changes. So I guess it works.
2024-04-19 15:27:18 +10:00
Leon Friedrich
36eaa8c941 Make station components use StationPostInitEvent (#27126) 2024-04-19 15:26:56 +10:00
Leon Friedrich
8245caaf61 Hide some map related logs from clients (#27127)
* Hide some map related logs from clients

* #if !DEBUG

* Fix typo
2024-04-19 15:26:21 +10:00
DrSmugleaf
45df595c15 Fix storage fill giving no reason for failing (#27122) 2024-04-18 23:24:13 -04:00
Leon Friedrich
6ec40900ef Fix fixgridatmos command (#27113) 2024-04-18 19:39:38 -07:00
PJBot
f9f098f64e Automatic changelog update 2024-04-18 23:44:07 +00:00
Iztok Bajcar
f56373321a Made glass more opaque (#26948)
* Made glass more opaque

* Made glass a bit less opaque
2024-04-18 19:43:01 -04:00
PJBot
77090fca62 Automatic changelog update 2024-04-18 23:42:17 +00:00
Whisper
7decf64c39 Raise difficulty class of RD hardsuit objective (#27103)
Raise difficulty class of RD hardsuit
2024-04-18 19:41:11 -04:00
PJBot
5a89fe0395 Automatic changelog update 2024-04-18 23:39:31 +00:00
Mr. 27
c8202dd80d add roboticist gear to science loadout (#27045)
* inital

* yes

* g

* death

* DEATH
2024-04-18 19:38:17 -04:00
lzk
d5e187dc50 Changes to frills axolotl (#27104) 2024-04-18 19:02:21 -04:00
deltanedas
4509235604 saltern update (#27071)
Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-04-18 16:05:38 -06:00
deltanedas
71d5d2a563 atlas update (#27070)
Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-04-18 16:05:29 -06:00
Mr. 27
620a6de0ff Fix duplicate science backpack for reserach assistant (#27096)
Update research_assistant.yml
2024-04-19 07:44:55 +10:00
Ed
1eba437555 Merge pull request #100 from crystallpunk-14/17-04-2024-melting
+Ores
2024-04-19 00:15:59 +03:00
Ed
98503cca7c Update tiles.yml 2024-04-18 23:41:02 +03:00
Ed
81d2a4730e Merge pull request #99 from crystallpunk-14/revert-90-nospawn
Revert "NoSpawn markers and weapons"
2024-04-18 23:37:32 +03:00
Ed
0b4c5bb988 +2 ores 2024-04-18 23:34:45 +03:00
Ed
05ca2baa3d Revert "NoSpawn markers and weapons (#90)"
This reverts commit 3dff87b3e1.
2024-04-18 22:56:51 +03:00
Ed
02bcfc4593 revert melting 2024-04-18 22:45:01 +03:00
Ed
79b4ae3998 add wall destructions 2024-04-18 22:37:49 +03:00
Whisper
f801a86351 fix RD hardsuit description (#27094) (#27095) 2024-04-18 14:47:35 -04:00
PJBot
10beb47e0f Automatic changelog update 2024-04-18 18:06:51 +00:00
Flareguy
77612e8e51 Nerfs the Experimental Research Hardsuit's size (#27094)
* nerfs rds hardsuit to be the size all other hardsuits are

* 4x4 > 5x5
2024-04-18 14:05:45 -04:00
Vasilis
5769bf38f8 Revert #26994 and #27077 (#27090) 2024-04-18 17:06:56 +02:00
PJBot
b14e6e31ea Automatic changelog update 2024-04-18 11:29:00 +00:00
Ed
e82034c16b Component of planet initialization on the map (#26510)
* no cl no fun

* DevPlanet

* fix europa?

* Update Content.Server/Station/Components/StationBiomeComponent.cs

* Update Content.Server/Station/Components/StationBiomeComponent.cs

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-18 21:27:54 +10:00
PJBot
403852cd01 Automatic changelog update 2024-04-18 11:23:02 +00:00
Ed
f3a97fc0c5 Killer tomatoes (#26053)
* make tomatoes

* many friends! many mommies

* finish

* renaming system

* fix

* Update miscellaneous.yml

* Update Content.Server/NPC/Systems/NPCImpritingBehaviourSystem.cs

Co-authored-by: faint <46868845+ficcialfaint@users.noreply.github.com>

* N

* deleete exception?

* merge conflict fix

* fix?

* fuck you

* sloth fixes

* fixess?

* fix

---------

Co-authored-by: faint <46868845+ficcialfaint@users.noreply.github.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-04-18 21:21:56 +10:00
Ed
59b8757f14 add iron and ore fragments items 2024-04-18 14:16:09 +03:00
PJBot
0b0e20ea41 Automatic changelog update 2024-04-18 10:53:39 +00:00
Mr. 27
73a5a3830d Chemists now start with chemical analysis goggles (#27047)
Update chemist.yml
2024-04-18 20:52:33 +10:00
PJBot
a66e233839 Automatic changelog update 2024-04-18 10:51:17 +00:00
Velcroboy
394390b35b Adds plasma windoors for Armory, Sec, Command, and Atmos (#26149)
* Adds plasma windoors for Armory, Sec, Command

* Adds atmos too

---------

Co-authored-by: Jeff <velcroboy333@hotmail.com>
2024-04-18 20:51:13 +10:00
superjj18
ebf87be9f2 Emergency Lights now changes color depending on alert level and whether or not the light is powered. (#26932)
* Emergency Lights now change color depending on alert level and whether or not they are powered.

* Made a condition for null alert level, added summary doc.

* Refactored uid and emergencylightcomponent into Entity<EmergencyLightComponent>
2024-04-18 20:50:08 +10:00
Ed
390249f0cc add ore vein wall dumb proto 2024-04-18 13:37:16 +03:00
Ed
dc1b38054e add iron and gold ore 2024-04-18 12:53:15 +03:00
Flareguy
7b94e244b3 Ports a fuckton of vox clothing from Paradise and /vg/station (#27021)
* adds a bunch of vox clothing sprites

* bird up

* bee mask

* fix test fails. i hope. this better be the only damn one

* fix "eqipped"

* A.

* outerclohting

* ???

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-18 16:43:42 +10:00
Detintinto
5b9e0fb08e Fixing the cryogenic section of the guidebook (#26803)
Its fixed, but the cryopod is being partially covered by text and the caption is not aligned to the captions next to it. No clue how to fix this, but good enough for me.
2024-04-18 16:33:33 +10:00
Nemanja
3af744e4a9 Flash buff (#25730)
* flash buff

* oops!

* bool

* 3 -> 1.5 seconds

* okay fix

* sluth
2024-04-18 16:30:01 +10:00
Hannah Giovanna Dawson
b1136c98d7 Chatfactor: Chat Repository, Admin Commands, Chat Created Events (#26113)
* Chatfactor: Chat Repository, Admin Commands, Chat Created Events

This addition-only PR covers a repository that stores chat messages.
This PR defines what chat messages can be stored, what can be done
with those stored messages, and what events occur when the repository
does things.

This PR also includes to admin commands that show how the repository
will be used for administration purposes at first. Because all chat
messages will be uniquely identified per round (and, as rounds are
uniquely identified, are essentially a GUID) we can delete, amend
or nuke messages.

Note there's no "amend" command right now. The original chatfactor PR
didn't include one, and I'm avoiding further feature bloat with these
chatfactor PRs...

* Remove an event that shouldn't be in this PR

* Resolve PR comments.

* Resolve peak goober moment

* Also make sure we tell the user why if their delete command fails

* Supply a reason if the nukeuserids command is malformed

* Tidy messages

* Some more docstring tidyup

* Imagine tests handling IOC correctly chat

* Imagine tests handling IOC correctly chat

* Resolve PR comments

* Fix goobering with needing to use ToolshedCommand

* In which we bikeshed toolshed

* loud metal pipe sound effect

* One must imagine funny boulder pushing man happy

* Move commands to new folder

* Mald, seethe, cope.

* I hate toolshed I hate toolshed I hate toolshed

* Fix command ftls

* Bit of tidy-up and a YAGNI removal of a get we don't need yet

* Whelp lmao

* UserIDs are in a weird fucky state I didn't anticipate, so I've removed the remove-by-userID command for the time being.

* Rename ChatRepository to ChatRepositorySystem.

* Resolve PR review comments

---------

Co-authored-by: Your Name <you@example.com>
2024-04-18 14:59:10 +10:00
metalgearsloth
126f64a914 Fix merg conflict (#27080)
bo
2024-04-18 14:36:40 +10:00
Leon Friedrich
ee96d8aa66 Content changes for MapManager/System refactor (#26994)
* Content changes for MapManager/System refactor

* Poke Tests

* Why is this failing?

* Will this make the analyzer happy?
2024-04-18 14:30:06 +10:00
metalgearsloth
20452ba5bb Update submodule to 219.0.0 (#27077) 2024-04-18 14:20:41 +10:00
Errant
7120e8736a Cleanup in HumanoidCharacterAppearance (#26974)
* namespace

* Tidy up the code for selecting random humanoid color
2024-04-18 13:27:11 +10:00
PJBot
24a0298f76 Automatic changelog update 2024-04-18 03:25:21 +00:00
ArZarLordOfMango
94aa61b323 Add recipe of beverage jug (#25681)
* Add craft of beverage jug

* Change steel to plastic

* Fix price
2024-04-18 13:24:15 +10:00
PJBot
31f88ec865 Automatic changelog update 2024-04-18 03:21:50 +00:00
Krunklehorn
460b588de5 Refactor status icons take 2, cyborgs don't see criminal status (#26207)
* Initial commit.

* review

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-18 13:20:44 +10:00
PJBot
020f322e27 Automatic changelog update 2024-04-18 03:05:19 +00:00
Golinth
a3750f0e64 Nukie Medivisor REAL (#26218)
* Nukie Medihud REAL

adds a new HUD that the nukie agent starts with, does the same shit as the other visor, but with health bars. Also tinted slightly blue to differentiate it. (also medhuds are blue)

* the blue-ening

makes the icons bluer 'cause someone asked.
2024-04-18 13:04:14 +10:00
Token
8d21ef0aa2 Rebalance: From Insuzine recipe removed Benzene (#26829)
* From Insuzine recipe removed Benzene

* Remove ash from Insuzine recipe
2024-04-18 13:03:39 +10:00
PJBot
d9ee1600ee Automatic changelog update 2024-04-18 03:02:18 +00:00
metalgearsloth
9b1a8b07d7 Fix loadouts UI not refreshing on char change (#27075)
I love lobby code. Refreshing the entire jobs UI doesn't seem to cause issues. At least jobpriorityselector was my fault when I was far fucking stupider writing this shit.
2024-04-18 13:01:12 +10:00
Pancake
3c1ec9ac34 Add Hardhats to Station Engineer Loadouts (#27044)
* Add hardhats to loadout.

* Update Resources/Prototypes/Loadouts/Jobs/Engineering/station_engineer.yml

* Update Resources/Prototypes/Loadouts/loadout_groups.yml

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-18 13:00:55 +10:00
PJBot
b672ea73f0 Automatic changelog update 2024-04-18 01:51:04 +00:00
Tayrtahn
cfa94be4c2 Add ability to shake fizzy drinks so they spray in peoples' faces (#25574)
* Implemented Shakeable

* Prevent shaking open Openables

* Prevent shaking empty drinks. Moved part of DrinkSystem to Shared.

* DrinkSystem can have a little more prediction, as a treat

* Cleanup

* Overhauled PressurizedDrink

* Make soda cans/bottles and champagne shakeable. The drink shaker too, for fun.

* We do a little refactoring.
PressurizedDrink is now PressurizedSolution, and fizziness now only works on solutions containing a reagent marked as fizzy.

* Documentation, cleanup, and tweaks.

* Changed fizziness calculation to use a cubic-out easing curve.

* Removed broken YAML that has avoid the linter's wrath for far too long

* Changed reagent fizzy bool to fizziness float.
Solution fizzability now scales with reagent proportion.

* Rename file to match changed class name

* DoAfter improvements. Cancel if the user moves away; block if no hands.

* Match these filenames too

* And this one

* guh

* Updated to use Shared puddle methods

* Various fixes and improvements.

* Made AttemptShakeEvent a struct

* AttemptAddFizzinessEvent too
2024-04-18 11:49:58 +10:00
PJBot
8d64d2bc1e Automatic changelog update 2024-04-18 01:23:15 +00:00
Mr. 27
06ecf2af05 add greysec loadout (#27023)
* inital

* George orwell
2024-04-17 21:22:09 -04:00
deepdarkdepths
b3ee929f1b Reduces the captain's sabre reflect chance to 10% (#26969)
add
2024-04-18 11:21:04 +10:00
PJBot
ac8d3d55cc Automatic changelog update 2024-04-18 01:17:54 +00:00
MisterMecky
4453fe50cf fix soap popup (#27054)
fix soap
2024-04-17 21:17:18 -04:00
Flareguy
66f32d4289 Partially reverts the remote signaller resprite (#27073)
de-sprites the remote signaller
2024-04-17 21:16:48 -04:00
PJBot
d76211514b Automatic changelog update 2024-04-18 01:07:39 +00:00
Bellwether
8213c89fdb Low-Key Zombie Rebalance (#27060)
initial soft zombie rebalance - lower infection chance, damage, and chance of outbreak

Co-authored-by: Bellwether <null>
2024-04-17 21:06:33 -04:00
Ghagliiarghii
40d90ddcb3 Make Holy Water more like Water (#27068)
holy water can now be used to satiate thirst, water plants, and extinguish fires.
2024-04-17 21:04:56 -04:00
PJBot
45cefc9643 Automatic changelog update 2024-04-18 00:33:27 +00:00
icekot8
fd109d61b8 cargo console radio messages on approving (#27038)
* 1

* void --> "Unknown"
2024-04-17 17:32:21 -07:00
PJBot
92089da192 Automatic changelog update 2024-04-18 00:09:12 +00:00
Ed
5659edd207 Chances of triggering effects (#27056)
* electrocution

* slippery

* flashibg

* Update SlipperyComponent.cs

* Update SlipperySystem.cs
2024-04-18 10:08:42 +10:00
Krunklehorn
d67d782f99 Standardize HoS/Warden winter coats, add unarmored variants for printing (#24865)
* Both winter coats with same armor as their counterparts

* Matching description for HoS's, unarmored variants for balancing the uniform printer

* Forgot some text

* New sprite provided by PursuitinAshes, old sprite moved to unarmored version

* Removed the 'unarmored' specifier, in line with the rest of the winter coats

* Remove unarmored warden, no sprite

* Re-implemented the warden's unarmored coat, with sprites from Dutch-VanDerLinde

* CRLF to LF

* Move armor values to abstract
2024-04-18 10:08:06 +10:00
PJBot
d2dc0734df Automatic changelog update 2024-04-17 22:17:30 +00:00
ShadowCommander
a95fc86f7a Fix PDA and ID card data not getting set on loadouts (#27062) 2024-04-18 00:16:24 +02:00
Emisse
da136826e7 box update (#27069)
* box update

* argh
2024-04-17 16:01:24 -06:00
PJBot
a376f4784a Automatic changelog update 2024-04-17 21:49:42 +00:00
deltanedas
395c33024c prop hunt ss14 (real) (#26691)
* texture appropriation

* add code for projector

* add chameleon projector yml

* damage and actions

* prevent small props being killed round removing you (700 damage from a single shot)

* tweak default

* oop

* do appearance properly, need engine update

* fix bugs, blacklist pda

* remove status icons

* amou

* sus

* fix test + make props fast

* amouuuung

* remove funny log

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-04-17 14:48:35 -07:00
deltanedas
46733616df atlas artifact update (#26506)
atlas update

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-04-17 15:36:29 -06:00
deltanedas
d08600240f saltern update (#26507)
* saltern update

* update atmos too

* run fixgridatmos

* fix power outside botany, fix botany air alarm

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-04-17 15:36:18 -06:00
Emisse
f2ed508562 meta update (#27067) 2024-04-17 15:25:03 -06:00
Emisse
e0589a1350 fland update (#27064)
* fland update

* n2 lockers
2024-04-17 15:08:41 -06:00
chromiumboy
009d06d978 Navmap rework (#26713)
* Optimized the drawing of lines and tracked entities

* Optimized nav map updating and added thin wall support

* Added support for thin doors

* Removed floor tile seams, more line drawing optimizations

* Fixed split grids not updating correctly

* Cleaned up NavMapControl code

* Fix nav map header

* Converted nav map updates from system network messages to delta-states

* Addressed review comments

* Fixed timing issue where NavMapSystem would update before AirtightSystem did
2024-04-17 12:59:31 -05:00
PJBot
20b16944ad Automatic changelog update 2024-04-17 17:43:30 +00:00
Ed
c5b4df22a6 modified cave wall 2024-04-17 20:42:28 +03:00
slarticodefast
5a5efa11cf Show volume on the gas analyzer (#25720)
The gas analyzer now shows the volume of pipes, tanks, canisters and the environment.

Adjust gas analyzers so that the volume and number of moles shown corresponds to only the scanned element, e.g. a canister or single pipe in a pipenet.
2024-04-17 09:42:24 -08:00
Ed
e94cd726e1 init melting reagent and system 2024-04-17 17:49:47 +03:00
Pieter-Jan Briers
ef72d3cf7f Revert "Update .editorconfig to correspond Code Conventions" (#27051)
Revert "Update .editorconfig to correspond Code Conventions (#26824)"

This reverts commit 882aeb0314.
2024-04-17 15:42:06 +02:00
lzk
24390ef51b Make cargo pallets smoothing with eachother (#27049) 2024-04-17 23:22:09 +10:00
PJBot
9f461dec5a Automatic changelog update 2024-04-17 10:11:09 +00:00
beck-thompson
afcdc8b866 Fixed gloved weapons being able to attack when not equipped. (#26762)
* Initial commit. No evil hidden files this time :)

* Added newline because I forgot :(

* We <3 tags :)

* Fixed! Works now

* Update Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-17 20:10:03 +10:00
PJBot
0785516eac Automatic changelog update 2024-04-17 10:07:16 +00:00
metalgearsloth
f9f204a6d0 Fix character preview not updating on character change (#27043)
I love lobby code :3
2024-04-17 20:06:10 +10:00
PJBot
03f51ca3aa Automatic changelog update 2024-04-17 10:05:30 +00:00
Verm
432e6ec45d Fix capitalization for pirates and rats (#26644)
* Fix capitalization for pirates and rats

* Deal with replacements better

* Be smarter about caps

* Do last word properly

* Variables named a bit better

* Fix Consistency

* Undo change that's not needed anymore

* Fix up pirate since it doesn't need to check early either

* Make mobster replacin' a bit better anyway

* Remove extra space

* Use capture groups for mobster in', add comments for first and last words

* Slightly more clarification with comments
2024-04-17 20:04:24 +10:00
Alfred Baumann
5b8468c9d8 Mobs auto state handlers (#26957)
* Autogenerate MobStateComponentState

* changed CurrentState to DataField, updated DataField attribute for AllowedStates

* Update Content.Shared/Mobs/Components/MobStateComponent.cs

* Update Content.Shared/Mobs/Components/MobStateComponent.cs

---------

Co-authored-by: BuildTools <unconfigured@null.spigotmc.org>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-04-17 20:00:05 +10:00
lzk
e2341c0089 Add jani gloves loadout (#27011) 2024-04-17 19:38:49 +10:00
PJBot
ceef55b8d3 Automatic changelog update 2024-04-17 09:28:08 +00:00
metalgearsloth
2db374988c Added Jukebox (#26736)
* Added Jukebox, along with music for jukebox

* Fixed Jukebox meta.json copyright

* Removed songs I couldn't find a license for.

* Renamed files to solve check failures from spaces

* Added missing attributions.yml

* Fixed lack of description in Jukebox

* Jukebox is now constructable.

* Change Jukebox menu to FancyWindow

* Moved Jukebox messages out of jukebox component

* Removed Jukebox OnValueChanged.

* JukeboxComp now uses AutoGenerateComponentState

* Removed state code, since it's auto generated

* Fixed various Jukebox code to match conventions.

* Updated Standard.yml to match changed song list.

* fixes

* Jukebox workin

* Fix

* Polishing

* Finalising

* Revert

* bad

* jukey

* Reviews

* name

* Update submodule to 218.2.0

---------

Co-authored-by: iNVERTED <alextjorgensen@gmail.com>
2024-04-17 19:27:00 +10:00
metalgearsloth
177d69cb98 Update submodule to 218.2.0 (#27041) 2024-04-17 19:10:53 +10:00
4116 changed files with 263983 additions and 48171 deletions

View File

@@ -9,9 +9,10 @@ indent_style = space
tab_width = 4
# New line preferences
end_of_line = crlf:suggestion
#end_of_line = crlf
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 120
#### .NET Coding Conventions ####
@@ -104,7 +105,6 @@ csharp_preferred_modifier_order = public, private, protected, internal, new, abs
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:silent
csharp_style_namespace_declarations = file_scoped:suggestion
#### C# Formatting Rules ####
@@ -337,7 +337,11 @@ dotnet_naming_symbols.type_parameters_symbols.applicable_kinds = type_parameter
# ReSharper properties
resharper_braces_for_ifelse = required_for_multiline
resharper_csharp_wrap_arguments_style = chop_if_long
resharper_csharp_wrap_parameters_style = chop_if_long
resharper_keep_existing_attribute_arrangement = true
resharper_wrap_chained_binary_patterns = chop_if_long
resharper_wrap_chained_method_calls = chop_if_long
[*.{csproj,xml,yml,yaml,dll.config,msbuildproj,targets,props}]
indent_size = 2

16
.github/labeler.yml vendored
View File

@@ -1,12 +1,18 @@
"Changes: Sprites":
- '**/*.rsi/*.png'
- changed-files:
- any-glob-to-any-file: '**/*.rsi/*.png'
"Changes: Map":
- 'Resources/Maps/*.yml'
- 'Resources/Prototypes/Maps/*.yml'
- changed-files:
- any-glob-to-any-file:
- 'Resources/Maps/*.yml'
- 'Resources/Prototypes/Maps/*.yml'
"Changes: UI":
- '**/*.xaml*'
- changed-files:
- any-glob-to-any-file: '**/*.xaml*'
"No C#":
- all: ["!**/*.cs"]
- changed-files:
# Equiv to any-glob-to-all as long as this has one matcher. If ALL changed files are not C# files, then apply label.
- all-globs-to-all-files: "!**/*.cs"

View File

@@ -1,18 +1,20 @@
name: Check Merge Conflicts
on:
push:
branches:
- master
pull_request_target:
types:
- opened
- synchronize
- reopened
- ready_for_review
jobs:
Label:
if: github.actor != 'PJBot'
if: ( github.event.pull_request.draft == false ) && ( github.actor != 'PJBot' )
runs-on: ubuntu-latest
steps:
- name: Check for Merge Conflicts
uses: ike709/actions-label-merge-conflict@9eefdd17e10566023c46d2dc6dc04fcb8ec76142
uses: eps1lon/actions-label-merge-conflict@v3.0.0
with:
dirtyLabel: "Merge Conflict"
repoToken: "${{ secrets.GITHUB_TOKEN }}"

View File

@@ -6,8 +6,9 @@ on:
jobs:
labeler:
if: github.actor != 'PJBot'
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v3
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
- uses: actions/labeler@v5

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -46,7 +46,7 @@ public class MapLoadBenchmark
PoolManager.Shutdown();
}
public static readonly string[] MapsSource = { "Empty", "Box", "Bagel", "Dev", "CentComm", "Atlas", "Core", "TestTeg", "Saltern", "Packed", "Omega", "Cluster", "Reach", "Origin", "Meta", "Marathon", "Europa", "MeteorArena", "Fland", "Barratry" };
public static readonly string[] MapsSource = { "Empty", "Box", "Bagel", "Dev", "CentComm", "Atlas", "Core", "TestTeg", "Saltern", "Packed", "Omega", "Cluster", "Reach", "Origin", "Meta", "Marathon", "Europa", "MeteorArena", "Fland", "Barratry", "Oasis" };
[ParamsSource(nameof(MapsSource))]
public string Map;

View File

@@ -2,6 +2,4 @@
namespace Content.Client.Access;
public sealed class IdCardSystem : SharedIdCardSystem
{
}
public sealed class IdCardSystem : SharedIdCardSystem;

View File

@@ -40,9 +40,9 @@ namespace Content.Client.Access.UI
SendMessage(new AgentIDCardJobChangedMessage(newJob));
}
public void OnJobIconChanged(string newJobIcon)
public void OnJobIconChanged(string newJobIconId)
{
SendMessage(new AgentIDCardJobIconChangedMessage(newJobIcon));
SendMessage(new AgentIDCardJobIconChangedMessage(newJobIconId));
}
/// <summary>
@@ -57,7 +57,7 @@ namespace Content.Client.Access.UI
_window.SetCurrentName(cast.CurrentName);
_window.SetCurrentJob(cast.CurrentJob);
_window.SetAllowedIcons(cast.Icons);
_window.SetAllowedIcons(cast.Icons, cast.CurrentJobIconId);
}
protected override void Dispose(bool disposing)

View File

@@ -38,7 +38,7 @@ namespace Content.Client.Access.UI
JobLineEdit.OnFocusExit += e => OnJobChanged?.Invoke(e.Text);
}
public void SetAllowedIcons(HashSet<string> icons)
public void SetAllowedIcons(HashSet<string> icons, string currentJobIconId)
{
IconGrid.DisposeAllChildren();
@@ -79,6 +79,10 @@ namespace Content.Client.Access.UI
jobIconButton.AddChild(jobIconTexture);
jobIconButton.OnPressed += _ => _bui.OnJobIconChanged(jobIcon.ID);
IconGrid.AddChild(jobIconButton);
if (jobIconId.Equals(currentJobIconId))
jobIconButton.Pressed = true;
i++;
}
}

View File

@@ -3,7 +3,7 @@ using Robust.Shared.GameStates;
namespace Content.Client.Administration.Components;
[RegisterComponent, NetworkedComponent]
[RegisterComponent]
public sealed partial class HeadstandComponent : SharedHeadstandComponent
{

View File

@@ -3,6 +3,5 @@ using Robust.Shared.GameStates;
namespace Content.Client.Administration.Components;
[NetworkedComponent, RegisterComponent]
public sealed partial class KillSignComponent : SharedKillSignComponent
{ }
[RegisterComponent]
public sealed partial class KillSignComponent : SharedKillSignComponent;

View File

@@ -126,12 +126,15 @@ namespace Content.Client.Administration.Managers
public AdminData? GetAdminData(EntityUid uid, bool includeDeAdmin = false)
{
return uid == _player.LocalEntity ? _adminData : null;
if (uid == _player.LocalEntity && (_adminData?.Active ?? includeDeAdmin))
return _adminData;
return null;
}
public AdminData? GetAdminData(ICommonSession session, bool includeDeAdmin = false)
{
if (_player.LocalUser == session.UserId)
if (_player.LocalUser == session.UserId && (_adminData?.Active ?? includeDeAdmin))
return _adminData;
return null;

View File

@@ -1,3 +1,6 @@
using Content.Shared.Administration;
using Content.Shared.Administration.Managers;
using Content.Shared.Mind.Components;
using Content.Shared.Verbs;
using Robust.Client.Console;
using Robust.Shared.Utility;
@@ -11,10 +14,12 @@ namespace Content.Client.Administration.Systems
{
[Dependency] private readonly IClientConGroupController _clientConGroupController = default!;
[Dependency] private readonly IClientConsoleHost _clientConsoleHost = default!;
[Dependency] private readonly ISharedAdminManager _admin = default!;
public override void Initialize()
{
SubscribeLocalEvent<GetVerbsEvent<Verb>>(AddAdminVerbs);
}
private void AddAdminVerbs(GetVerbsEvent<Verb> args)
@@ -33,6 +38,24 @@ namespace Content.Client.Administration.Systems
};
args.Verbs.Add(verb);
}
if (!_admin.IsAdmin(args.User))
return;
if (_admin.HasAdminFlag(args.User, AdminFlags.Admin))
args.ExtraCategories.Add(VerbCategory.Admin);
if (_admin.HasAdminFlag(args.User, AdminFlags.Fun) && HasComp<MindContainerComponent>(args.Target))
args.ExtraCategories.Add(VerbCategory.Antag);
if (_admin.HasAdminFlag(args.User, AdminFlags.Debug))
args.ExtraCategories.Add(VerbCategory.Debug);
if (_admin.HasAdminFlag(args.User, AdminFlags.Fun))
args.ExtraCategories.Add(VerbCategory.Smite);
if (_admin.HasAdminFlag(args.User, AdminFlags.Admin))
args.ExtraCategories.Add(VerbCategory.Tricks);
}
}
}

View File

@@ -3,6 +3,7 @@ using System.Net;
using System.Net.Sockets;
using Content.Client.Administration.UI.CustomControls;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Database;
using Content.Shared.Roles;
using Robust.Client.AutoGenerated;
@@ -11,6 +12,7 @@ using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -32,8 +34,11 @@ public sealed partial class BanPanel : DefaultWindow
// This is less efficient than just holding a reference to the root control and enumerating children, but you
// have to know how the controls are nested, which makes the code more complicated.
private readonly List<CheckBox> _roleCheckboxes = new();
private readonly ISawmill _banpanelSawmill;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly ILogManager _logManager = default!;
private enum TabNumbers
{
@@ -65,6 +70,7 @@ public sealed partial class BanPanel : DefaultWindow
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_banpanelSawmill = _logManager.GetSawmill("admin.banpanel");
PlayerList.OnSelectionChanged += OnPlayerSelectionChanged;
PlayerNameLine.OnFocusExit += _ => OnPlayerNameChanged();
PlayerCheckbox.OnPressed += _ =>
@@ -104,6 +110,11 @@ public sealed partial class BanPanel : DefaultWindow
};
SubmitButton.OnPressed += SubmitButtonOnOnPressed;
IpCheckbox.Pressed = _cfg.GetCVar(CCVars.ServerBanIpBanDefault);
HwidCheckbox.Pressed = _cfg.GetCVar(CCVars.ServerBanHwidBanDefault);
LastConnCheckbox.Pressed = _cfg.GetCVar(CCVars.ServerBanUseLastDetails);
EraseCheckbox.Pressed = _cfg.GetCVar(CCVars.ServerBanErasePlayer);
SeverityOption.AddItem(Loc.GetString("admin-note-editor-severity-none"), (int) NoteSeverity.None);
SeverityOption.AddItem(Loc.GetString("admin-note-editor-severity-low"), (int) NoteSeverity.Minor);
SeverityOption.AddItem(Loc.GetString("admin-note-editor-severity-medium"), (int) NoteSeverity.Medium);
@@ -175,6 +186,39 @@ public sealed partial class BanPanel : DefaultWindow
c.Pressed = args.Pressed;
}
}
if (args.Pressed)
{
if (!Enum.TryParse(_cfg.GetCVar(CCVars.DepartmentBanDefaultSeverity), true, out NoteSeverity newSeverity))
{
_banpanelSawmill
.Warning("Departmental role ban severity could not be parsed from config!");
return;
}
SeverityOption.SelectId((int) newSeverity);
}
else
{
foreach (var childContainer in RolesContainer.Children)
{
if (childContainer is Container)
{
foreach (var child in childContainer.Children)
{
if (child is CheckBox { Pressed: true })
return;
}
}
}
if (!Enum.TryParse(_cfg.GetCVar(CCVars.RoleBanDefaultSeverity), true, out NoteSeverity newSeverity))
{
_banpanelSawmill
.Warning("Role ban severity could not be parsed from config!");
return;
}
SeverityOption.SelectId((int) newSeverity);
}
};
outerContainer.AddChild(innerContainer);
foreach (var role in roleList)
@@ -353,6 +397,35 @@ public sealed partial class BanPanel : DefaultWindow
{
TypeOption.ModulateSelfOverride = null;
Tabs.SetTabVisible((int) TabNumbers.Roles, TypeOption.SelectedId == (int) Types.Role);
NoteSeverity? newSeverity = null;
switch (TypeOption.SelectedId)
{
case (int)Types.Server:
if (Enum.TryParse(_cfg.GetCVar(CCVars.ServerBanDefaultSeverity), true, out NoteSeverity serverSeverity))
newSeverity = serverSeverity;
else
{
_banpanelSawmill
.Warning("Server ban severity could not be parsed from config!");
}
break;
case (int) Types.Role:
if (Enum.TryParse(_cfg.GetCVar(CCVars.RoleBanDefaultSeverity), true, out NoteSeverity roleSeverity))
{
newSeverity = roleSeverity;
}
else
{
_banpanelSawmill
.Warning("Role ban severity could not be parsed from config!");
}
break;
}
if (newSeverity != null)
SeverityOption.SelectId((int) newSeverity.Value);
}
private void UpdateSubmitEnabled()

View File

@@ -0,0 +1,17 @@
using System.Numerics;
namespace Content.Client.Animations;
/// <summary>
/// Entities with this component tracks the user's world position every frame.
/// </summary>
[RegisterComponent]
public sealed partial class TrackUserComponent : Component
{
public EntityUid? User;
/// <summary>
/// Offset in the direction of the entity's rotation.
/// </summary>
public Vector2 Offset = Vector2.Zero;
}

View File

@@ -163,6 +163,26 @@ namespace Content.Client.Atmos.UI
parent.AddChild(panel);
panel.AddChild(dataContainer);
// Volume label
var volBox = new BoxContainer { Orientation = BoxContainer.LayoutOrientation.Horizontal };
volBox.AddChild(new Label
{
Text = Loc.GetString("gas-analyzer-window-volume-text")
});
volBox.AddChild(new Control
{
MinSize = new Vector2(10, 0),
HorizontalExpand = true
});
volBox.AddChild(new Label
{
Text = Loc.GetString("gas-analyzer-window-volume-val-text", ("volume", $"{gasMix.Volume:0.##}")),
Align = Label.AlignMode.Right,
HorizontalExpand = true
});
dataContainer.AddChild(volBox);
// Pressure label
var presBox = new BoxContainer { Orientation = BoxContainer.LayoutOrientation.Horizontal };

View File

@@ -0,0 +1,119 @@
using Content.Shared.Audio.Jukebox;
using Robust.Client.Audio;
using Robust.Client.Player;
using Robust.Shared.Audio.Components;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
namespace Content.Client.Audio.Jukebox;
public sealed class JukeboxBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[ViewVariables]
private JukeboxMenu? _menu;
public JukeboxBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
protected override void Open()
{
base.Open();
_menu = new JukeboxMenu();
_menu.OnClose += Close;
_menu.OpenCentered();
_menu.OnPlayPressed += args =>
{
if (args)
{
SendMessage(new JukeboxPlayingMessage());
}
else
{
SendMessage(new JukeboxPauseMessage());
}
};
_menu.OnStopPressed += () =>
{
SendMessage(new JukeboxStopMessage());
};
_menu.OnSongSelected += SelectSong;
_menu.SetTime += SetTime;
PopulateMusic();
Reload();
}
/// <summary>
/// Reloads the attached menu if it exists.
/// </summary>
public void Reload()
{
if (_menu == null || !EntMan.TryGetComponent(Owner, out JukeboxComponent? jukebox))
return;
_menu.SetAudioStream(jukebox.AudioStream);
if (_protoManager.TryIndex(jukebox.SelectedSongId, out var songProto))
{
var length = EntMan.System<AudioSystem>().GetAudioLength(songProto.Path.Path.ToString());
_menu.SetSelectedSong(songProto.Name, (float) length.TotalSeconds);
}
else
{
_menu.SetSelectedSong(string.Empty, 0f);
}
}
public void PopulateMusic()
{
_menu?.Populate(_protoManager.EnumeratePrototypes<JukeboxPrototype>());
}
public void SelectSong(ProtoId<JukeboxPrototype> songid)
{
SendMessage(new JukeboxSelectedMessage(songid));
}
public void SetTime(float time)
{
var sentTime = time;
// You may be wondering, what the fuck is this
// Well we want to be able to predict the playback slider change, of which there are many ways to do it
// We can't just use SendPredictedMessage because it will reset every tick and audio updates every frame
// so it will go BRRRRT
// Using ping gets us close enough that it SHOULD, MOST OF THE TIME, fall within the 0.1 second tolerance
// that's still on engine so our playback position never gets corrected.
if (EntMan.TryGetComponent(Owner, out JukeboxComponent? jukebox) &&
EntMan.TryGetComponent(jukebox.AudioStream, out AudioComponent? audioComp))
{
audioComp.PlaybackPosition = time;
}
SendMessage(new JukeboxSetTimeMessage(sentTime));
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
if (_menu == null)
return;
_menu.OnClose -= Close;
_menu.Dispose();
_menu = null;
}
}

View File

@@ -0,0 +1,18 @@
<ui:FancyWindow xmlns="https://spacestation14.io" xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls"
SetSize="400 500" Title="{Loc 'jukebox-menu-title'}">
<BoxContainer Margin="4 0" Orientation="Vertical">
<ItemList Name="MusicList" SelectMode="Button" Margin="3 3 3 3"
HorizontalExpand="True" VerticalExpand="True" SizeFlagsStretchRatio="8"/>
<BoxContainer Orientation="Vertical">
<Label Name="SongSelected" Text="{Loc 'jukebox-menu-selectedsong'}" />
<Label Name="SongName" Text="---" />
<Slider Name="PlaybackSlider" HorizontalExpand="True" />
</BoxContainer>
<BoxContainer Orientation="Horizontal" HorizontalExpand="True"
VerticalExpand="False" SizeFlagsStretchRatio="1">
<Button Name="PlayButton" Text="{Loc 'jukebox-menu-buttonplay'}" />
<Button Name="StopButton" Text="{Loc 'jukebox-menu-buttonstop'}" />
<Label Name="DurationLabel" Text="00:00 / 00:00" HorizontalAlignment="Right" HorizontalExpand="True"/>
</BoxContainer>
</BoxContainer>
</ui:FancyWindow>

View File

@@ -0,0 +1,166 @@
using Content.Shared.Audio.Jukebox;
using Robust.Client.Audio;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Audio.Components;
using Robust.Shared.Input;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow;
namespace Content.Client.Audio.Jukebox;
[GenerateTypedNameReferences]
public sealed partial class JukeboxMenu : FancyWindow
{
[Dependency] private readonly IEntityManager _entManager = default!;
private AudioSystem _audioSystem;
/// <summary>
/// Are we currently 'playing' or paused for the play / pause button.
/// </summary>
private bool _playState;
/// <summary>
/// True if playing, false if paused.
/// </summary>
public event Action<bool>? OnPlayPressed;
public event Action? OnStopPressed;
public event Action<ProtoId<JukeboxPrototype>>? OnSongSelected;
public event Action<float>? SetTime;
private EntityUid? _audio;
private float _lockTimer;
public JukeboxMenu()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_audioSystem = _entManager.System<AudioSystem>();
MusicList.OnItemSelected += args =>
{
var entry = MusicList[args.ItemIndex];
if (entry.Metadata is not string juke)
return;
OnSongSelected?.Invoke(juke);
};
PlayButton.OnPressed += args =>
{
OnPlayPressed?.Invoke(!_playState);
};
StopButton.OnPressed += args =>
{
OnStopPressed?.Invoke();
};
PlaybackSlider.OnReleased += PlaybackSliderKeyUp;
SetPlayPauseButton(_audioSystem.IsPlaying(_audio), force: true);
}
public JukeboxMenu(AudioSystem audioSystem)
{
_audioSystem = audioSystem;
}
public void SetAudioStream(EntityUid? audio)
{
_audio = audio;
}
private void PlaybackSliderKeyUp(Slider args)
{
SetTime?.Invoke(PlaybackSlider.Value);
_lockTimer = 0.5f;
}
/// <summary>
/// Re-populates the list of jukebox prototypes available.
/// </summary>
public void Populate(IEnumerable<JukeboxPrototype> jukeboxProtos)
{
MusicList.Clear();
foreach (var entry in jukeboxProtos)
{
MusicList.AddItem(entry.Name, metadata: entry.ID);
}
}
public void SetPlayPauseButton(bool playing, bool force = false)
{
if (_playState == playing && !force)
return;
_playState = playing;
if (playing)
{
PlayButton.Text = Loc.GetString("jukebox-menu-buttonpause");
return;
}
PlayButton.Text = Loc.GetString("jukebox-menu-buttonplay");
}
public void SetSelectedSong(string name, float length)
{
SetSelectedSongText(name);
PlaybackSlider.MaxValue = length;
PlaybackSlider.SetValueWithoutEvent(0);
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if (_lockTimer > 0f)
{
_lockTimer -= args.DeltaSeconds;
}
PlaybackSlider.Disabled = _lockTimer > 0f;
if (_entManager.TryGetComponent(_audio, out AudioComponent? audio))
{
DurationLabel.Text = $@"{TimeSpan.FromSeconds(audio.PlaybackPosition):mm\:ss} / {_audioSystem.GetAudioLength(audio.FileName):mm\:ss}";
}
else
{
DurationLabel.Text = $"00:00 / 00:00";
}
if (PlaybackSlider.Grabbed)
return;
if (audio != null || _entManager.TryGetComponent(_audio, out audio))
{
PlaybackSlider.SetValueWithoutEvent(audio.PlaybackPosition);
}
else
{
PlaybackSlider.SetValueWithoutEvent(0f);
}
SetPlayPauseButton(_audioSystem.IsPlaying(_audio, audio));
}
public void SetSelectedSongText(string? text)
{
if (!string.IsNullOrEmpty(text))
{
SongName.Text = text;
}
else
{
SongName.Text = "---";
}
}
}

View File

@@ -0,0 +1,145 @@
using Content.Shared.Audio.Jukebox;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.Client.Audio.Jukebox;
public sealed class JukeboxSystem : SharedJukeboxSystem
{
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
[Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<JukeboxComponent, AppearanceChangeEvent>(OnAppearanceChange);
SubscribeLocalEvent<JukeboxComponent, AnimationCompletedEvent>(OnAnimationCompleted);
SubscribeLocalEvent<JukeboxComponent, AfterAutoHandleStateEvent>(OnJukeboxAfterState);
_protoManager.PrototypesReloaded += OnProtoReload;
}
public override void Shutdown()
{
base.Shutdown();
_protoManager.PrototypesReloaded -= OnProtoReload;
}
private void OnProtoReload(PrototypesReloadedEventArgs obj)
{
if (!obj.WasModified<JukeboxPrototype>())
return;
var query = AllEntityQuery<JukeboxComponent, UserInterfaceComponent>();
while (query.MoveNext(out var uid, out _, out var ui))
{
if (!_uiSystem.TryGetOpenUi<JukeboxBoundUserInterface>((uid, ui), JukeboxUiKey.Key, out var bui))
continue;
bui.PopulateMusic();
}
}
private void OnJukeboxAfterState(Entity<JukeboxComponent> ent, ref AfterAutoHandleStateEvent args)
{
if (!_uiSystem.TryGetOpenUi<JukeboxBoundUserInterface>(ent.Owner, JukeboxUiKey.Key, out var bui))
return;
bui.Reload();
}
private void OnAnimationCompleted(EntityUid uid, JukeboxComponent component, AnimationCompletedEvent args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;
if (!TryComp<AppearanceComponent>(uid, out var appearance) ||
!_appearanceSystem.TryGetData<JukeboxVisualState>(uid, JukeboxVisuals.VisualState, out var visualState, appearance))
{
visualState = JukeboxVisualState.On;
}
UpdateAppearance(uid, visualState, component, sprite);
}
private void OnAppearanceChange(EntityUid uid, JukeboxComponent component, ref AppearanceChangeEvent args)
{
if (args.Sprite == null)
return;
if (!args.AppearanceData.TryGetValue(JukeboxVisuals.VisualState, out var visualStateObject) ||
visualStateObject is not JukeboxVisualState visualState)
{
visualState = JukeboxVisualState.On;
}
UpdateAppearance(uid, visualState, component, args.Sprite);
}
private void UpdateAppearance(EntityUid uid, JukeboxVisualState visualState, JukeboxComponent component, SpriteComponent sprite)
{
SetLayerState(JukeboxVisualLayers.Base, component.OffState, sprite);
switch (visualState)
{
case JukeboxVisualState.On:
SetLayerState(JukeboxVisualLayers.Base, component.OnState, sprite);
break;
case JukeboxVisualState.Off:
SetLayerState(JukeboxVisualLayers.Base, component.OffState, sprite);
break;
case JukeboxVisualState.Select:
PlayAnimation(uid, JukeboxVisualLayers.Base, component.SelectState, 1.0f, sprite);
break;
}
}
private void PlayAnimation(EntityUid uid, JukeboxVisualLayers layer, string? state, float animationTime, SpriteComponent sprite)
{
if (string.IsNullOrEmpty(state))
return;
if (!_animationPlayer.HasRunningAnimation(uid, state))
{
var animation = GetAnimation(layer, state, animationTime);
sprite.LayerSetVisible(layer, true);
_animationPlayer.Play(uid, animation, state);
}
}
private static Animation GetAnimation(JukeboxVisualLayers layer, string state, float animationTime)
{
return new Animation
{
Length = TimeSpan.FromSeconds(animationTime),
AnimationTracks =
{
new AnimationTrackSpriteFlick
{
LayerKey = layer,
KeyFrames =
{
new AnimationTrackSpriteFlick.KeyFrame(state, 0f)
}
}
}
};
}
private void SetLayerState(JukeboxVisualLayers layer, string? state, SpriteComponent sprite)
{
if (string.IsNullOrEmpty(state))
return;
sprite.LayerSetVisible(layer, true);
sprite.LayerSetAutoAnimated(layer, true);
sprite.LayerSetState(layer, state);
}
}

View File

@@ -1,4 +1,5 @@
using System.Numerics;
using Content.Shared.Body.Components;
using Content.Shared.CardboardBox;
using Content.Shared.CardboardBox.Components;
using Content.Shared.Examine;
@@ -13,9 +14,14 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly ExamineSystemShared _examine = default!;
private EntityQuery<BodyComponent> _bodyQuery;
public override void Initialize()
{
base.Initialize();
_bodyQuery = GetEntityQuery<BodyComponent>();
SubscribeNetworkEvent<PlayBoxEffectMessage>(OnBoxEffect);
}
@@ -59,6 +65,10 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
if (!_examine.InRangeUnOccluded(sourcePos, mapPos, box.Distance, null))
continue;
// no effect for anything too exotic
if (!_bodyQuery.HasComp(mob))
continue;
var ent = Spawn(box.Effect, mapPos);
if (!xformQuery.TryGetComponent(ent, out var entTransform) || !TryComp<SpriteComponent>(ent, out var sprite))

View File

@@ -87,14 +87,12 @@ namespace Content.Client.Changelog
if (!tab.AdminOnly || isAdmin)
{
Tabs.SetTabVisible(i, true);
tab.Visible = true;
visibleTabs++;
firstVisible ??= i;
}
else
{
Tabs.SetTabVisible(i, false);
tab.Visible = false;
}
}

View File

@@ -0,0 +1,31 @@
<ui:RadialMenu xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls"
BackButtonStyleClass="RadialMenuBackButton"
CloseButtonStyleClass="RadialMenuCloseButton"
VerticalExpand="True"
HorizontalExpand="True"
MinSize="450 450">
<!-- Main -->
<ui:RadialContainer Name="Main" VerticalExpand="True" HorizontalExpand="True" Radius="64" ReserveSpaceForHiddenChildren="False">
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'emote-menu-category-general'}" TargetLayer="General" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/Clothing/Head/Soft/mimesoft.rsi/icon.png"/>
</ui:RadialMenuTextureButton>
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'emote-menu-category-vocal'}" TargetLayer="Vocal" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/Interface/Emotes/vocal.png"/>
</ui:RadialMenuTextureButton>
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'emote-menu-category-hands'}" TargetLayer="Hands" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/Clothing/Hands/Gloves/latex.rsi/icon.png"/>
</ui:RadialMenuTextureButton>
</ui:RadialContainer>
<!-- General -->
<ui:RadialContainer Name="General" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>
<!-- Vocal -->
<ui:RadialContainer Name="Vocal" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>
<!-- Hands -->
<ui:RadialContainer Name="Hands" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>
</ui:RadialMenu>

View File

@@ -0,0 +1,112 @@
using System.Numerics;
using Content.Client.UserInterface.Controls;
using Content.Shared.Chat.Prototypes;
using Content.Shared.Speech;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
namespace Content.Client.Chat.UI;
[GenerateTypedNameReferences]
public sealed partial class EmotesMenu : RadialMenu
{
[Dependency] private readonly EntityManager _entManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly ISharedPlayerManager _playerManager = default!;
private readonly SpriteSystem _spriteSystem;
public event Action<ProtoId<EmotePrototype>>? OnPlayEmote;
public EmotesMenu()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
_spriteSystem = _entManager.System<SpriteSystem>();
var main = FindControl<RadialContainer>("Main");
var emotes = _prototypeManager.EnumeratePrototypes<EmotePrototype>();
foreach (var emote in emotes)
{
var player = _playerManager.LocalSession?.AttachedEntity;
if (emote.Category == EmoteCategory.Invalid ||
emote.ChatTriggers.Count == 0 ||
!(player.HasValue && (emote.Whitelist?.IsValid(player.Value, _entManager) ?? true)) ||
(emote.Blacklist?.IsValid(player.Value, _entManager) ?? false))
continue;
if (!emote.Available &&
_entManager.TryGetComponent<SpeechComponent>(player.Value, out var speech) &&
!speech.AllowedEmotes.Contains(emote.ID))
continue;
var parent = FindControl<RadialContainer>(emote.Category.ToString());
var button = new EmoteMenuButton
{
StyleClasses = { "RadialMenuButton" },
SetSize = new Vector2(64f, 64f),
ToolTip = Loc.GetString(emote.Name),
ProtoId = emote.ID,
};
var tex = new TextureRect
{
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center,
Texture = _spriteSystem.Frame0(emote.Icon),
TextureScale = new Vector2(2f, 2f),
};
button.AddChild(tex);
parent.AddChild(button);
foreach (var child in main.Children)
{
if (child is not RadialMenuTextureButton castChild)
continue;
if (castChild.TargetLayer == emote.Category.ToString())
{
castChild.Visible = true;
break;
}
}
}
// Set up menu actions
foreach (var child in Children)
{
if (child is not RadialContainer container)
continue;
AddEmoteClickAction(container);
}
}
private void AddEmoteClickAction(RadialContainer container)
{
foreach (var child in container.Children)
{
if (child is not EmoteMenuButton castChild)
continue;
castChild.OnButtonUp += _ =>
{
OnPlayEmote?.Invoke(castChild.ProtoId);
Close();
};
}
}
}
public sealed class EmoteMenuButton : RadialMenuTextureButton
{
public ProtoId<EmotePrototype> ProtoId { get; set; }
}

View File

@@ -0,0 +1,22 @@
using Content.Client.Chemistry.EntitySystems;
using Content.Client.Chemistry.UI;
namespace Content.Client.Chemistry.Components;
/// <summary>
/// Exposes a solution container's contents via a basic item status control.
/// </summary>
/// <remarks>
/// Shows the solution volume, max volume, and transfer amount.
/// </remarks>
/// <seealso cref="SolutionItemStatusSystem"/>
/// <seealso cref="SolutionStatusControl"/>
[RegisterComponent]
public sealed partial class SolutionItemStatusComponent : Component
{
/// <summary>
/// The ID of the solution that will be shown on the item status control.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public string Solution = "default";
}

View File

@@ -0,0 +1,22 @@
using Content.Client.Chemistry.Components;
using Content.Client.Chemistry.UI;
using Content.Client.Items;
using Content.Shared.Chemistry.EntitySystems;
namespace Content.Client.Chemistry.EntitySystems;
/// <summary>
/// Wires up item status logic for <see cref="SolutionItemStatusComponent"/>.
/// </summary>
/// <seealso cref="SolutionStatusControl"/>
public sealed class SolutionItemStatusSystem : EntitySystem
{
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!;
public override void Initialize()
{
base.Initialize();
Subs.ItemStatus<SolutionItemStatusComponent>(
entity => new SolutionStatusControl(entity, EntityManager, _solutionContainerSystem));
}
}

View File

@@ -32,7 +32,7 @@ public sealed class InjectorStatusControl : Control
{
base.FrameUpdate(args);
if (!_solutionContainers.TryGetSolution(_parent.Owner, InjectorComponent.SolutionName, out _, out var solution))
if (!_solutionContainers.TryGetSolution(_parent.Owner, _parent.Comp.SolutionName, out _, out var solution))
return;
// only updates the UI if any of the details are different than they previously were

View File

@@ -0,0 +1,59 @@
using Content.Client.Chemistry.Components;
using Content.Client.Chemistry.EntitySystems;
using Content.Client.Items.UI;
using Content.Client.Message;
using Content.Client.Stylesheets;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.FixedPoint;
using Robust.Client.UserInterface.Controls;
namespace Content.Client.Chemistry.UI;
/// <summary>
/// Displays basic solution information for <see cref="SolutionItemStatusComponent"/>.
/// </summary>
/// <seealso cref="SolutionItemStatusSystem"/>
public sealed class SolutionStatusControl : PollingItemStatusControl<SolutionStatusControl.Data>
{
private readonly Entity<SolutionItemStatusComponent> _parent;
private readonly IEntityManager _entityManager;
private readonly SharedSolutionContainerSystem _solutionContainers;
private readonly RichTextLabel _label;
public SolutionStatusControl(
Entity<SolutionItemStatusComponent> parent,
IEntityManager entityManager,
SharedSolutionContainerSystem solutionContainers)
{
_parent = parent;
_entityManager = entityManager;
_solutionContainers = solutionContainers;
_label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
AddChild(_label);
}
protected override Data PollData()
{
if (!_solutionContainers.TryGetSolution(_parent.Owner, _parent.Comp.Solution, out _, out var solution))
return default;
FixedPoint2? transferAmount = null;
if (_entityManager.TryGetComponent(_parent.Owner, out SolutionTransferComponent? transfer))
transferAmount = transfer.TransferAmount;
return new Data(solution.Volume, solution.MaxVolume, transferAmount);
}
protected override void Update(in Data data)
{
var markup = Loc.GetString("solution-status-volume",
("currentVolume", data.Volume),
("maxVolume", data.MaxVolume));
if (data.TransferVolume is { } transferVolume)
markup += "\n" + Loc.GetString("solution-status-transfer", ("volume", transferVolume));
_label.SetMarkup(markup);
}
public readonly record struct Data(FixedPoint2 Volume, FixedPoint2 MaxVolume, FixedPoint2? TransferVolume);
}

View File

@@ -11,6 +11,7 @@ using Content.Shared.Item;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.TypeSerializers.Implementations;
using Robust.Shared.Utility;
using static Robust.Client.GameObjects.SpriteComponent;
@@ -53,6 +54,7 @@ public sealed class ClientClothingSystem : ClothingSystem
};
[Dependency] private readonly IResourceCache _cache = default!;
[Dependency] private readonly ISerializationManager _serialization = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!;
public override void Initialize()
@@ -272,6 +274,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 displacementData = inventory.Displacements.GetValueOrDefault(slot);
// add the new layers
foreach (var (key, layerData) in ev.Layers)
@@ -315,6 +318,28 @@ public sealed class ClientClothingSystem : ClothingSystem
sprite.LayerSetData(index, layerData);
layer.Offset += slotDef.Offset;
if (displacementData != null)
{
if (displacementData.ShaderOverride != null)
sprite.LayerSetShader(index, displacementData.ShaderOverride);
var displacementKey = $"{key}-displacement";
if (!revealedLayers.Add(displacementKey))
{
Log.Warning($"Duplicate key for clothing visuals DISPLACEMENT: {displacementKey}.");
continue;
}
var displacementLayer = _serialization.CreateCopy(displacementData.Layer, notNullableOverride: true);
displacementLayer.CopyToShaderParameters!.LayerKey = key;
// Add before main layer for this item.
sprite.AddLayer(displacementLayer, index);
sprite.LayerMapSet(displacementKey, index);
revealedLayers.Add(displacementKey);
}
}
RaiseLocalEvent(equipment, new EquipmentVisualsUpdatedEvent(equipee, slot, revealedLayers), true);

View File

@@ -1,7 +1,9 @@
using Content.Client.UserInterface.Controls;
using System.Threading;
using Content.Shared.CCVar;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Configuration;
using Robust.Shared.Utility;
using Timer = Robust.Shared.Timing.Timer;
@@ -13,6 +15,8 @@ namespace Content.Client.Communications.UI
private CommunicationsConsoleBoundUserInterface Owner { get; set; }
private readonly CancellationTokenSource _timerCancelTokenSource = new();
[Dependency] private readonly IConfigurationManager _cfg = default!;
public CommunicationsConsoleMenu(CommunicationsConsoleBoundUserInterface owner)
{
IoCManager.InjectDependencies(this);
@@ -23,6 +27,22 @@ namespace Content.Client.Communications.UI
var loc = IoCManager.Resolve<ILocalizationManager>();
MessageInput.Placeholder = new Rope.Leaf(loc.GetString("comms-console-menu-announcement-placeholder"));
var maxAnnounceLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength);
MessageInput.OnTextChanged += (args) =>
{
if (args.Control.TextLength > maxAnnounceLength)
{
AnnounceButton.Disabled = true;
AnnounceButton.ToolTip = Loc.GetString("comms-console-message-too-long");
}
else
{
AnnounceButton.Disabled = !owner.CanAnnounce;
AnnounceButton.ToolTip = null;
}
};
AnnounceButton.OnPressed += (_) => Owner.AnnounceButtonPressed(Rope.Collapse(MessageInput.TextRope));
AnnounceButton.Disabled = !owner.CanAnnounce;

View File

@@ -0,0 +1,8 @@
using Content.Shared.Radio.EntitySystems;
namespace Content.Client.DeviceNetwork;
public sealed class JammerSystem : SharedJammerSystem
{
}

View File

@@ -21,7 +21,7 @@ public sealed class DoAfterOverlay : Overlay
private readonly ProgressColorSystem _progressColor;
private readonly Texture _barTexture;
private readonly ShaderInstance _shader;
private readonly ShaderInstance _unshadedShader;
/// <summary>
/// Flash time for cancelled DoAfters
@@ -45,7 +45,7 @@ public sealed class DoAfterOverlay : Overlay
var sprite = new SpriteSpecifier.Rsi(new("/Textures/Interface/Misc/progress_bar.rsi"), "icon");
_barTexture = _entManager.EntitySysManager.GetEntitySystem<SpriteSystem>().Frame0(sprite);
_shader = protoManager.Index<ShaderPrototype>("unshaded").Instance();
_unshadedShader = protoManager.Index<ShaderPrototype>("unshaded").Instance();
}
protected override void Draw(in OverlayDrawArgs args)
@@ -58,7 +58,6 @@ public sealed class DoAfterOverlay : Overlay
const float scale = 1f;
var scaleMatrix = Matrix3.CreateScale(new Vector2(scale, scale));
var rotationMatrix = Matrix3.CreateRotation(-rotation);
handle.UseShader(_shader);
var curTime = _timing.CurTime;
@@ -79,6 +78,13 @@ public sealed class DoAfterOverlay : Overlay
if (!bounds.Contains(worldPosition))
continue;
// shades the do-after bar if the do-after bar belongs to other players
// does not shade do-afters belonging to the local player
if (uid != localEnt)
handle.UseShader(null);
else
handle.UseShader(_unshadedShader);
// If the entity is paused, we will draw the do-after as it was when the entity got paused.
var meta = metaQuery.GetComponent(uid);
var time = meta.EntityPaused

View File

@@ -119,6 +119,7 @@ namespace Content.Client.Entry
_prototypeManager.RegisterIgnore("wireLayout");
_prototypeManager.RegisterIgnore("alertLevels");
_prototypeManager.RegisterIgnore("nukeopsRole");
_prototypeManager.RegisterIgnore("ghostRoleRaffleDecider");
_componentFactory.GenerateNetIds();
_adminManager.Initialize();

View File

@@ -3,7 +3,5 @@ using Robust.Shared.GameStates;
namespace Content.Client.Extinguisher;
[NetworkedComponent, RegisterComponent]
public sealed partial class FireExtinguisherComponent : SharedFireExtinguisherComponent
{
}
[RegisterComponent]
public sealed partial class FireExtinguisherComponent : SharedFireExtinguisherComponent;

View File

@@ -86,7 +86,7 @@ public sealed class EyeLerpingSystem : EntitySystem
private void HandleMapChange(EntityUid uid, LerpingEyeComponent component, ref EntParentChangedMessage args)
{
// Is this actually a map change? If yes, stop any lerps
if (args.OldMapId != args.Transform.MapID)
if (args.OldMapId != args.Transform.MapUid)
component.LastRotation = GetRotation(uid, args.Transform);
}

View File

@@ -0,0 +1,48 @@
using Robust.Client.GameObjects;
using Content.Shared.Fax.Components;
using Content.Shared.Fax;
using Robust.Client.Animations;
namespace Content.Client.Fax.System;
/// <summary>
/// Visualizer for the fax machine which displays the correct sprite based on the inserted entity.
/// </summary>
public sealed class FaxVisualsSystem : EntitySystem
{
[Dependency] private readonly AnimationPlayerSystem _player = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<FaxMachineComponent, AppearanceChangeEvent>(OnAppearanceChanged);
}
private void OnAppearanceChanged(EntityUid uid, FaxMachineComponent component, ref AppearanceChangeEvent args)
{
if (args.Sprite == null)
return;
if (_appearance.TryGetData(uid, FaxMachineVisuals.VisualState, out FaxMachineVisualState visuals) && visuals == FaxMachineVisualState.Inserting)
{
_player.Play(uid, new Animation()
{
Length = TimeSpan.FromSeconds(2.4),
AnimationTracks =
{
new AnimationTrackSpriteFlick()
{
LayerKey = FaxMachineVisuals.VisualState,
KeyFrames =
{
new AnimationTrackSpriteFlick.KeyFrame(component.InsertingState, 0f),
new AnimationTrackSpriteFlick.KeyFrame("icon", 2.4f),
}
}
}
}, "faxecute");
}
}
}

View File

@@ -40,7 +40,7 @@ public sealed class FaxBoundUi : BoundUserInterface
{
if (_dialogIsOpen)
return;
_dialogIsOpen = true;
var filters = new FileDialogFilters(new FileDialogFilters.Group("txt"));
await using var file = await _fileDialogManager.OpenFile(filters);
@@ -52,8 +52,27 @@ public sealed class FaxBoundUi : BoundUserInterface
}
using var reader = new StreamReader(file);
var firstLine = await reader.ReadLineAsync();
string? label = null;
var content = await reader.ReadToEndAsync();
SendMessage(new FaxFileMessage(content[..Math.Min(content.Length, FaxFileMessageValidation.MaxContentSize)], _window.OfficePaper));
if (firstLine is { })
{
if (firstLine.StartsWith('#'))
{
label = firstLine[1..].Trim();
}
else
{
content = firstLine + "\n" + content;
}
}
SendMessage(new FaxFileMessage(
label?[..Math.Min(label.Length, FaxFileMessageValidation.MaxLabelSize)],
content[..Math.Min(content.Length, FaxFileMessageValidation.MaxContentSize)],
_window.OfficePaper));
}
private void OnSendButtonPressed()

View File

@@ -1,3 +1,4 @@
using Content.Client.Administration.Managers;
using Content.Client.Gameplay;
using Content.Client.Lobby;
using Content.Client.RoundEnd;
@@ -6,7 +7,7 @@ using Content.Shared.GameWindow;
using JetBrains.Annotations;
using Robust.Client.Graphics;
using Robust.Client.State;
using Robust.Shared.Utility;
using Robust.Client.UserInterface;
namespace Content.Client.GameTicking.Managers
{
@@ -14,17 +15,14 @@ namespace Content.Client.GameTicking.Managers
public sealed class ClientGameTicker : SharedGameTicker
{
[Dependency] private readonly IStateManager _stateManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IClientAdminManager _admin = default!;
[Dependency] private readonly IClyde _clyde = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
[ViewVariables] private bool _initialized;
private Dictionary<NetEntity, Dictionary<string, uint?>> _jobsAvailable = new();
private Dictionary<NetEntity, string> _stationNames = new();
/// <summary>
/// The current round-end window. Could be used to support re-opening the window after closing it.
/// </summary>
private RoundEndSummaryWindow? _window;
[ViewVariables] public bool AreWeReady { get; private set; }
[ViewVariables] public bool IsGameStarted { get; private set; }
[ViewVariables] public string? RestartSound { get; private set; }
@@ -44,8 +42,6 @@ namespace Content.Client.GameTicking.Managers
public override void Initialize()
{
DebugTools.Assert(!_initialized);
SubscribeNetworkEvent<TickerJoinLobbyEvent>(JoinLobby);
SubscribeNetworkEvent<TickerJoinGameEvent>(JoinGame);
SubscribeNetworkEvent<TickerConnectionStatusEvent>(ConnectionStatus);
@@ -53,14 +49,33 @@ namespace Content.Client.GameTicking.Managers
SubscribeNetworkEvent<TickerLobbyInfoEvent>(LobbyInfo);
SubscribeNetworkEvent<TickerLobbyCountdownEvent>(LobbyCountdown);
SubscribeNetworkEvent<RoundEndMessageEvent>(RoundEnd);
SubscribeNetworkEvent<RequestWindowAttentionEvent>(msg =>
{
IoCManager.Resolve<IClyde>().RequestWindowAttention();
});
SubscribeNetworkEvent<RequestWindowAttentionEvent>(OnAttentionRequest);
SubscribeNetworkEvent<TickerLateJoinStatusEvent>(LateJoinStatus);
SubscribeNetworkEvent<TickerJobsAvailableEvent>(UpdateJobsAvailable);
_initialized = true;
_admin.AdminStatusUpdated += OnAdminUpdated;
OnAdminUpdated();
}
public override void Shutdown()
{
_admin.AdminStatusUpdated -= OnAdminUpdated;
base.Shutdown();
}
private void OnAdminUpdated()
{
// Hide some map/grid related logs from clients. This is to try prevent some easy metagaming by just
// reading the console. E.g., logs like this one could leak the nuke station/grid:
// > Grid NT-Arrivals 1101 (122/n25896) changed parent. Old parent: map 10 (121/n25895). New parent: FTL (123/n26470)
#if !DEBUG
_map.Log.Level = _admin.IsAdmin() ? LogLevel.Info : LogLevel.Warning;
#endif
}
private void OnAttentionRequest(RequestWindowAttentionEvent ev)
{
_clyde.RequestWindowAttention();
}
private void LateJoinStatus(TickerLateJoinStatusEvent message)
@@ -132,12 +147,7 @@ namespace Content.Client.GameTicking.Managers
// Force an update in the event of this song being the same as the last.
RestartSound = message.RestartSound;
// Don't open duplicate windows (mainly for replays).
if (_window?.RoundId == message.RoundId)
return;
//This is not ideal at all, but I don't see an immediately better fit anywhere else.
_window = new RoundEndSummaryWindow(message.GamemodeTitle, message.RoundEndText, message.RoundDuration, message.RoundId, message.AllPlayersEndInfo, _entityManager);
_userInterfaceManager.GetUIController<RoundEndSummaryUIController>().OpenRoundEndSummaryWindow(message);
}
}
}

View File

@@ -0,0 +1,26 @@
using Robust.Shared.Console;
namespace Content.Client.Ghost.Commands;
public sealed class ToggleGhostVisibilityCommand : IConsoleCommand
{
[Dependency] private readonly IEntitySystemManager _entSysMan = default!;
public string Command => "toggleghostvisibility";
public string Description => "Toggles ghost visibility on the client.";
public string Help => "toggleghostvisibility [bool]";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var ghostSystem = _entSysMan.GetEntitySystem<GhostSystem>();
if (args.Length != 0 && bool.TryParse(args[0], out var visibility))
{
ghostSystem.ToggleGhostVisibility(visibility);
}
else
{
ghostSystem.ToggleGhostVisibility();
}
}
}

View File

@@ -3,7 +3,6 @@ using Content.Shared.Actions;
using Content.Shared.Ghost;
using Robust.Client.Console;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Player;
@@ -177,9 +176,9 @@ namespace Content.Client.Ghost
_console.RemoteExecuteCommand(null, "ghostroles");
}
public void ToggleGhostVisibility()
public void ToggleGhostVisibility(bool? visibility = null)
{
GhostVisibility = !GhostVisibility;
GhostVisibility = visibility ?? !GhostVisibility;
}
}
}

View File

@@ -4,6 +4,7 @@ using Content.Client.Chemistry.EntitySystems;
using Content.Client.Guidebook.Richtext;
using Content.Client.Message;
using Content.Client.UserInterface.ControlExtensions;
using Content.Shared.Body.Prototypes;
using Content.Shared.Chemistry.Reaction;
using Content.Shared.Chemistry.Reagent;
using JetBrains.Annotations;
@@ -128,7 +129,7 @@ public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISea
var groupLabel = new RichTextLabel();
groupLabel.SetMarkup(Loc.GetString("guidebook-reagent-effects-metabolism-group-rate",
("group", group), ("rate", effect.MetabolismRate)));
("group", _prototype.Index<MetabolismGroupPrototype>(group).LocalizedName), ("rate", effect.MetabolismRate)));
var descriptionLabel = new RichTextLabel
{
Margin = new Thickness(25, 0, 10, 0)

View File

@@ -136,6 +136,7 @@ public sealed partial class GuidebookWindow : FancyWindow, ILinkClickHandler
TreeItem? parent = forcedRoot == null ? null : AddEntry(forcedRoot, null, addedEntries);
foreach (var entry in GetSortedEntries(roots))
{
if (!entry.CrystallPunkAllowed) continue; //CrystallPunk guidebook filter
AddEntry(entry.Id, parent, addedEntries);
}
Tree.SetAllExpanded(true);

View File

@@ -39,10 +39,13 @@ public class GuideEntry
/// If the guide is the child of some other guide, the order simply determined by the order of children in <see cref="Children"/>.
/// </summary>
[DataField("priority")] public int Priority = 0;
[DataField]
public bool CrystallPunkAllowed = false;
}
[Prototype("guideEntry")]
public sealed class GuideEntryPrototype : GuideEntry, IPrototype
public sealed partial class GuideEntryPrototype : GuideEntry, IPrototype
{
public string ID => Id;
}

View File

@@ -13,6 +13,7 @@ using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -31,6 +32,8 @@ public sealed class GuidebookSystem : EntitySystem
[Dependency] private readonly SharedPointLightSystem _pointLightSystem = default!;
[Dependency] private readonly TagSystem _tags = default!;
[Dependency] private readonly IPrototypeManager _proto = default!; //CrystallPunk guidebook filter
public event Action<List<string>, List<string>?, string?, bool, string?>? OnGuidebookOpen;
public const string GuideEmbedTag = "GuideEmbeded";
@@ -39,6 +42,7 @@ public sealed class GuidebookSystem : EntitySystem
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<GuideHelpComponent, MapInitEvent>(OnCrystallPunkMapInit); //CrystallPunk guidebook filter
SubscribeLocalEvent<GuideHelpComponent, GetVerbsEvent<ExamineVerb>>(OnGetVerbs);
SubscribeLocalEvent<GuideHelpComponent, ActivateInWorldEvent>(OnInteract);
@@ -48,6 +52,21 @@ public sealed class GuidebookSystem : EntitySystem
OnGuidebookControlsTestGetAlternateVerbs);
}
//CrystallPunk guidebook filter
private void OnCrystallPunkMapInit(Entity<GuideHelpComponent> ent, ref MapInitEvent args)
{
foreach (var guide in ent.Comp.Guides)
{
var guideProto = _proto.Index<GuideEntryPrototype>(guide);
if (!guideProto.CrystallPunkAllowed) //REMOVE unnecessary guidebook
{
RemComp<GuideHelpComponent>(ent);
return;
}
}
}
//CrystallPunk guidebook filter end
/// <summary>
/// Gets a user entity to use for verbs and examinations. If the player has no attached entity, this will use a
/// dummy client-side entity so that users can still use the guidebook when not attached to anything (e.g., in the

View File

@@ -139,7 +139,7 @@ namespace Content.Client.HealthAnalyzer.UI
var groupTitleText = $"{Loc.GetString(
"health-analyzer-window-damage-group-text",
("damageGroup", Loc.GetString("health-analyzer-window-damage-group-" + damageGroupId)),
("damageGroup", _prototypes.Index<DamageGroupPrototype>(damageGroupId).LocalizedName),
("amount", damageAmount)
)}";
@@ -170,7 +170,7 @@ namespace Content.Client.HealthAnalyzer.UI
var damageString = Loc.GetString(
"health-analyzer-window-damage-type-text",
("damageType", Loc.GetString("health-analyzer-window-damage-type-" + type)),
("damageType", _prototypes.Index<DamageTypePrototype>(type).LocalizedName),
("amount", typeAmount)
);

View File

@@ -108,8 +108,11 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
/// This should not be used if the entity is owned by the server. The server will otherwise
/// override this with the appearance data it sends over.
/// </remarks>
public override void LoadProfile(EntityUid uid, HumanoidCharacterProfile profile, HumanoidAppearanceComponent? humanoid = null)
public override void LoadProfile(EntityUid uid, HumanoidCharacterProfile? profile, HumanoidAppearanceComponent? humanoid = null)
{
if (profile == null)
return;
if (!Resolve(uid, ref humanoid))
{
return;

View File

@@ -1,5 +1,6 @@
using Content.Client.Message;
using Content.Client.Stylesheets;
using Content.Client.UserInterface.Controls;
using Content.Shared.Implants.Components;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
@@ -17,7 +18,7 @@ public sealed class ImplanterStatusControl : Control
_parent = parent;
_label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
_label.MaxWidth = 350;
AddChild(_label);
AddChild(new ClipControl { Children = { _label } });
Update();
}
@@ -42,17 +43,12 @@ public sealed class ImplanterStatusControl : Control
_ => Loc.GetString("injector-invalid-injector-toggle-mode")
};
var (implantName, implantDescription) = _parent.ImplanterSlot.HasItem switch
{
false => (Loc.GetString("implanter-empty-text"), ""),
true => (_parent.ImplantData.Item1, _parent.ImplantData.Item2),
};
var implantName = _parent.ImplanterSlot.HasItem
? _parent.ImplantData.Item1
: Loc.GetString("implanter-empty-text");
_label.SetMarkup(Loc.GetString("implanter-label",
("implantName", implantName),
("implantDescription", implantDescription),
("modeString", modeStringLocalized),
("lineBreak", "\n")));
("modeString", modeStringLocalized)));
}
}

View File

@@ -38,6 +38,7 @@ namespace Content.Client.Input
common.AddFunction(ContentKeyFunctions.ZoomIn);
common.AddFunction(ContentKeyFunctions.ResetZoom);
common.AddFunction(ContentKeyFunctions.InspectEntity);
common.AddFunction(ContentKeyFunctions.ToggleRoundEndSummaryWindow);
// Not in engine, because engine cannot check for sanbox/admin status before starting placement.
common.AddFunction(ContentKeyFunctions.EditorCopyObject);
@@ -59,6 +60,7 @@ namespace Content.Client.Input
human.AddFunction(ContentKeyFunctions.UseItemInHand);
human.AddFunction(ContentKeyFunctions.AltUseItemInHand);
human.AddFunction(ContentKeyFunctions.OpenCharacterMenu);
human.AddFunction(ContentKeyFunctions.OpenEmotesMenu);
human.AddFunction(ContentKeyFunctions.ActivateItemInWorld);
human.AddFunction(ContentKeyFunctions.ThrowItemInHand);
human.AddFunction(ContentKeyFunctions.AltActivateItemInWorld);

View File

@@ -199,7 +199,7 @@ namespace Content.Client.Inventory
public void UIInventoryStorageActivate(string slot)
{
EntityManager.EntityNetManager?.SendSystemNetworkMessage(new OpenSlotStorageNetworkMessage(slot));
EntityManager.RaisePredictiveEvent(new OpenSlotStorageNetworkMessage(slot));
}
public void UIInventoryExamine(string slot, EntityUid uid)
@@ -251,6 +251,7 @@ namespace Content.Client.Inventory
public string SlotGroup => SlotDef.SlotGroup;
public string SlotDisplayName => SlotDef.DisplayName;
public string TextureName => "Slots/" + SlotDef.TextureName;
public string FullTextureName => SlotDef.FullTextureName;
public SlotData(SlotDefinition slotDef, ContainerSlot? container = null, bool highlighted = false,
bool blocked = false)

View File

@@ -219,7 +219,7 @@ namespace Content.Client.Inventory
if (entity == null)
{
button.SpriteView.SetEntity(null);
button.SetEntity(null);
return;
}
@@ -231,7 +231,7 @@ namespace Content.Client.Inventory
else
return;
button.SpriteView.SetEntity(viewEnt);
button.SetEntity(viewEnt);
}
}
}

View File

@@ -0,0 +1,28 @@
using Robust.Client.UserInterface;
using Robust.Shared.Timing;
namespace Content.Client.Items.UI;
/// <summary>
/// A base for item status controls that poll data every frame. Avoids UI updates if data didn't change.
/// </summary>
/// <typeparam name="TData">The full status control data that is polled every frame.</typeparam>
public abstract class PollingItemStatusControl<TData> : Control where TData : struct, IEquatable<TData>
{
private TData _lastData;
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
var newData = PollData();
if (newData.Equals(_lastData))
return;
_lastData = newData;
Update(newData);
}
protected abstract TData PollData();
protected abstract void Update(in TData data);
}

View File

@@ -0,0 +1,18 @@
using Content.Client.Labels.UI;
using Content.Shared.Labels;
using Content.Shared.Labels.Components;
using Content.Shared.Labels.EntitySystems;
namespace Content.Client.Labels.EntitySystems;
public sealed class HandLabelerSystem : SharedHandLabelerSystem
{
protected override void UpdateUI(Entity<HandLabelerComponent> ent)
{
if (UserInterfaceSystem.TryGetOpenUi(ent.Owner, HandLabelerUiKey.Key, out var bui)
&& bui is HandLabelerBoundUserInterface cBui)
{
cBui.Reload();
}
}
}

View File

@@ -1,4 +1,5 @@
using Content.Shared.Labels;
using Content.Shared.Labels.Components;
using Robust.Client.GameObjects;
namespace Content.Client.Labels.UI
@@ -8,11 +9,14 @@ namespace Content.Client.Labels.UI
/// </summary>
public sealed class HandLabelerBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IEntityManager _entManager = default!;
[ViewVariables]
private HandLabelerWindow? _window;
public HandLabelerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
protected override void Open()
@@ -27,24 +31,25 @@ namespace Content.Client.Labels.UI
_window.OnClose += Close;
_window.OnLabelChanged += OnLabelChanged;
Reload();
}
private void OnLabelChanged(string newLabel)
{
SendMessage(new HandLabelerLabelChangedMessage(newLabel));
}
/// <summary>
/// Update the UI state based on server-sent info
/// </summary>
/// <param name="state"></param>
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (_window == null || state is not HandLabelerBoundUserInterfaceState cast)
// Focus moment
if (_entManager.TryGetComponent(Owner, out HandLabelerComponent? labeler) &&
labeler.AssignedLabel.Equals(newLabel))
return;
_window.SetCurrentLabel(cast.CurrentLabel);
SendPredictedMessage(new HandLabelerLabelChangedMessage(newLabel));
}
public void Reload()
{
if (_window == null || !_entManager.TryGetComponent(Owner, out HandLabelerComponent? component))
return;
_window.SetCurrentLabel(component.AssignedLabel);
}
protected override void Dispose(bool disposing)

View File

@@ -9,17 +9,40 @@ namespace Content.Client.Labels.UI
{
public event Action<string>? OnLabelChanged;
/// <summary>
/// Is the user currently entering text into the control?
/// </summary>
private bool _focused;
// TODO LineEdit Make this a bool on the LineEdit control
private string _label = string.Empty;
public HandLabelerWindow()
{
RobustXamlLoader.Load(this);
LabelLineEdit.OnTextEntered += e => OnLabelChanged?.Invoke(e.Text);
LabelLineEdit.OnFocusExit += e => OnLabelChanged?.Invoke(e.Text);
LabelLineEdit.OnTextEntered += e =>
{
_label = e.Text;
OnLabelChanged?.Invoke(_label);
};
LabelLineEdit.OnFocusEnter += _ => _focused = true;
LabelLineEdit.OnFocusExit += _ =>
{
_focused = false;
LabelLineEdit.Text = _label;
};
}
public void SetCurrentLabel(string label)
{
LabelLineEdit.Text = label;
if (label == _label)
return;
_label = label;
if (!_focused)
LabelLineEdit.Text = label;
}
}
}

View File

@@ -10,6 +10,8 @@ using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.ResourceManagement;
using Robust.Client.Graphics;
using Robust.Shared.Prototypes;
namespace Content.Client.Lathe.UI;
@@ -19,6 +21,8 @@ public sealed partial class LatheMenu : DefaultWindow
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IResourceCache _resources = default!;
private EntityUid _owner;
private readonly SpriteSystem _spriteSystem;
private readonly LatheSystem _lathe;
@@ -104,12 +108,21 @@ public sealed partial class LatheMenu : DefaultWindow
RecipeList.Children.Clear();
foreach (var prototype in sortedRecipesToShow)
{
var icon = prototype.Icon == null
? _spriteSystem.GetPrototypeIcon(prototype.Result).Default
: _spriteSystem.Frame0(prototype.Icon);
List<Texture> textures;
if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto) && entityProto != null)
{
textures = SpriteComponent.GetPrototypeTextures(entityProto, _resources).Select(o => o.Default).ToList();
}
else
{
textures = prototype.Icon == null
? new List<Texture> { _spriteSystem.GetPrototypeIcon(prototype.Result).Default }
: new List<Texture> { _spriteSystem.Frame0(prototype.Icon) };
}
var canProduce = _lathe.CanProduce(_owner, prototype, quantity);
var control = new RecipeControl(prototype, () => GenerateTooltipText(prototype), canProduce, icon);
var control = new RecipeControl(prototype, () => GenerateTooltipText(prototype), canProduce, textures);
control.OnButtonPressed += s =>
{
if (!int.TryParse(AmountLineEdit.Text, out var amount) || amount <= 0)

View File

@@ -5,11 +5,15 @@
Margin="0"
StyleClasses="ButtonSquare">
<BoxContainer Orientation="Horizontal">
<TextureRect
Name="RecipeTexture"
<LayeredTextureRect
Name="RecipeTextures"
Margin="0 0 4 0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="KeepAspectCentered"
MinSize="32 32"
Stretch="KeepAspectCentered" />
CanShrink="true"
/>
<Label Name="RecipeName" HorizontalExpand="True" />
</BoxContainer>
</Button>

View File

@@ -2,8 +2,8 @@ using Content.Shared.Research.Prototypes;
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.Graphics;
namespace Content.Client.Lathe.UI;
@@ -13,12 +13,12 @@ public sealed partial class RecipeControl : Control
public Action<string>? OnButtonPressed;
public Func<string> TooltipTextSupplier;
public RecipeControl(LatheRecipePrototype recipe, Func<string> tooltipTextSupplier, bool canProduce, Texture? texture = null)
public RecipeControl(LatheRecipePrototype recipe, Func<string> tooltipTextSupplier, bool canProduce, List<Texture> textures)
{
RobustXamlLoader.Load(this);
RecipeName.Text = recipe.Name;
RecipeTexture.Texture = texture;
RecipeTextures.Textures = textures;
Button.Disabled = !canProduce;
TooltipTextSupplier = tooltipTextSupplier;
Button.TooltipSupplier = SupplyTooltip;

View File

@@ -52,7 +52,7 @@ public sealed class ExpendableLightSystem : VisualizerSystem<ExpendableLightComp
case ExpendableLightState.Lit:
_audioSystem.Stop(comp.PlayingStream);
comp.PlayingStream = _audioSystem.PlayPvs(
comp.LoopedSound, uid, SharedExpendableLightComponent.LoopedSoundParams)?.Entity;
comp.LoopedSound, uid)?.Entity;
if (args.Sprite.LayerMapTryGet(ExpendableLightVisualLayers.Overlay, out var layerIdx, true))
{

View File

@@ -72,9 +72,6 @@ public sealed class MagicMirrorBoundUserInterface : BoundUserInterface
if (!disposing)
return;
if (_window != null)
_window.OnClose -= Close;
_window?.Dispose();
}
}

View File

@@ -0,0 +1,8 @@
using Content.Shared.MagicMirror;
namespace Content.Client.MagicMirror;
public sealed class MagicMirrorSystem : SharedMagicMirrorSystem
{
}

View File

@@ -49,7 +49,7 @@ public sealed class MouseRotatorSystem : SharedMouseRotatorSystem
if (angleDir == curRot.GetCardinalDir())
return;
RaisePredictiveEvent(new RequestMouseRotatorRotationSimpleEvent()
RaisePredictiveEvent(new RequestMouseRotatorRotationSimpleEvent()
{
Direction = angleDir,
});

View File

@@ -88,6 +88,7 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
base.Dispose(disposing);
if (!disposing) return;
_linkMenu?.Dispose();
_listMenu?.Dispose();
_configurationMenu?.Dispose();
}

View File

@@ -0,0 +1,7 @@
using Content.Shared.Nutrition.EntitySystems;
namespace Content.Client.Nutrition.EntitySystems;
public sealed class DrinkSystem : SharedDrinkSystem
{
}

View File

@@ -36,6 +36,9 @@
<CheckBox Name="IntegerScalingCheckBox"
Text="{Loc 'ui-options-vp-integer-scaling'}"
ToolTip="{Loc 'ui-options-vp-integer-scaling-tooltip'}" />
<CheckBox Name="ViewportVerticalFitCheckBox"
Text="{Loc 'ui-options-vp-vertical-fit'}"
ToolTip="{Loc 'ui-options-vp-vertical-fit-tooltip'}" />
<CheckBox Name="ViewportLowResCheckBox" Text="{Loc 'ui-options-vp-low-res'}" />
<CheckBox Name="ParallaxLowQualityCheckBox" Text="{Loc 'ui-options-parallax-low-quality'}" />
<CheckBox Name="FpsCounterCheckBox" Text="{Loc 'ui-options-fps-counter'}" />

View File

@@ -67,6 +67,12 @@ namespace Content.Client.Options.UI.Tabs
UpdateApplyButton();
};
ViewportVerticalFitCheckBox.OnToggled += _ =>
{
UpdateViewportScale();
UpdateApplyButton();
};
IntegerScalingCheckBox.OnToggled += OnCheckBoxToggled;
ViewportLowResCheckBox.OnToggled += OnCheckBoxToggled;
ParallaxLowQualityCheckBox.OnToggled += OnCheckBoxToggled;
@@ -79,6 +85,7 @@ namespace Content.Client.Options.UI.Tabs
ViewportScaleSlider.Value = _cfg.GetCVar(CCVars.ViewportFixedScaleFactor);
ViewportStretchCheckBox.Pressed = _cfg.GetCVar(CCVars.ViewportStretch);
IntegerScalingCheckBox.Pressed = _cfg.GetCVar(CCVars.ViewportSnapToleranceMargin) != 0;
ViewportVerticalFitCheckBox.Pressed = _cfg.GetCVar(CCVars.ViewportVerticalFit);
ViewportLowResCheckBox.Pressed = !_cfg.GetCVar(CCVars.ViewportScaleRender);
ParallaxLowQualityCheckBox.Pressed = _cfg.GetCVar(CCVars.ParallaxLowQuality);
FpsCounterCheckBox.Pressed = _cfg.GetCVar(CCVars.HudFpsCounterVisible);
@@ -111,6 +118,7 @@ namespace Content.Client.Options.UI.Tabs
_cfg.SetCVar(CCVars.ViewportFixedScaleFactor, (int) ViewportScaleSlider.Value);
_cfg.SetCVar(CCVars.ViewportSnapToleranceMargin,
IntegerScalingCheckBox.Pressed ? CCVars.ViewportSnapToleranceMargin.DefaultValue : 0);
_cfg.SetCVar(CCVars.ViewportVerticalFit, ViewportVerticalFitCheckBox.Pressed);
_cfg.SetCVar(CCVars.ViewportScaleRender, !ViewportLowResCheckBox.Pressed);
_cfg.SetCVar(CCVars.ParallaxLowQuality, ParallaxLowQualityCheckBox.Pressed);
_cfg.SetCVar(CCVars.HudFpsCounterVisible, FpsCounterCheckBox.Pressed);
@@ -140,6 +148,7 @@ namespace Content.Client.Options.UI.Tabs
var isVPStretchSame = ViewportStretchCheckBox.Pressed == _cfg.GetCVar(CCVars.ViewportStretch);
var isVPScaleSame = (int) ViewportScaleSlider.Value == _cfg.GetCVar(CCVars.ViewportFixedScaleFactor);
var isIntegerScalingSame = IntegerScalingCheckBox.Pressed == (_cfg.GetCVar(CCVars.ViewportSnapToleranceMargin) != 0);
var isVPVerticalFitSame = ViewportVerticalFitCheckBox.Pressed == _cfg.GetCVar(CCVars.ViewportVerticalFit);
var isVPResSame = ViewportLowResCheckBox.Pressed == !_cfg.GetCVar(CCVars.ViewportScaleRender);
var isPLQSame = ParallaxLowQualityCheckBox.Pressed == _cfg.GetCVar(CCVars.ParallaxLowQuality);
var isFpsCounterVisibleSame = FpsCounterCheckBox.Pressed == _cfg.GetCVar(CCVars.HudFpsCounterVisible);
@@ -152,6 +161,7 @@ namespace Content.Client.Options.UI.Tabs
isVPStretchSame &&
isVPScaleSame &&
isIntegerScalingSame &&
isVPVerticalFitSame &&
isVPResSame &&
isPLQSame &&
isFpsCounterVisibleSame &&
@@ -235,6 +245,8 @@ namespace Content.Client.Options.UI.Tabs
{
ViewportScaleBox.Visible = !ViewportStretchCheckBox.Pressed;
IntegerScalingCheckBox.Visible = ViewportStretchCheckBox.Pressed;
ViewportVerticalFitCheckBox.Visible = ViewportStretchCheckBox.Pressed;
ViewportWidthSlider.Visible = ViewportWidthSliderDisplay.Visible = !ViewportStretchCheckBox.Pressed || ViewportStretchCheckBox.Pressed && !ViewportVerticalFitCheckBox.Pressed;
ViewportScaleText.Text = Loc.GetString("ui-options-vp-scale", ("scale", ViewportScaleSlider.Value));
}

View File

@@ -215,6 +215,7 @@ namespace Content.Client.Options.UI.Tabs
AddButton(ContentKeyFunctions.OpenInventoryMenu);
AddButton(ContentKeyFunctions.OpenAHelp);
AddButton(ContentKeyFunctions.OpenActionsMenu);
AddButton(ContentKeyFunctions.ToggleRoundEndSummaryWindow);
AddButton(ContentKeyFunctions.OpenEntitySpawnWindow);
AddButton(ContentKeyFunctions.OpenSandboxWindow);
AddButton(ContentKeyFunctions.OpenTileSpawnWindow);

View File

@@ -0,0 +1,28 @@
using Content.Shared.Overlays;
using Content.Shared.Security.Components;
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Shared.Prototypes;
namespace Content.Client.Overlays;
public sealed class ShowCriminalRecordIconsSystem : EquipmentHudSystem<ShowCriminalRecordIconsComponent>
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CriminalRecordComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
}
private void OnGetStatusIconsEvent(EntityUid uid, CriminalRecordComponent component, ref GetStatusIconsEvent ev)
{
if (!IsActive || ev.InContainer)
return;
if (_prototype.TryIndex<StatusIconPrototype>(component.StatusIcon.Id, out var iconPrototype))
ev.StatusIcons.Add(iconPrototype);
}
}

View File

@@ -1,14 +1,13 @@
using Content.Shared.Nutrition.EntitySystems;
using Content.Shared.Nutrition.Components;
using Content.Shared.Overlays;
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Shared.Prototypes;
namespace Content.Client.Overlays;
public sealed class ShowHungerIconsSystem : EquipmentHudSystem<ShowHungerIconsComponent>
{
[Dependency] private readonly IPrototypeManager _prototypeMan = default!;
[Dependency] private readonly HungerSystem _hunger = default!;
public override void Initialize()
{
@@ -17,42 +16,12 @@ public sealed class ShowHungerIconsSystem : EquipmentHudSystem<ShowHungerIconsCo
SubscribeLocalEvent<HungerComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
}
private void OnGetStatusIconsEvent(EntityUid uid, HungerComponent hungerComponent, ref GetStatusIconsEvent args)
private void OnGetStatusIconsEvent(EntityUid uid, HungerComponent component, ref GetStatusIconsEvent ev)
{
if (!IsActive || args.InContainer)
if (!IsActive || ev.InContainer)
return;
var hungerIcons = DecideHungerIcon(uid, hungerComponent);
args.StatusIcons.AddRange(hungerIcons);
}
private IReadOnlyList<StatusIconPrototype> DecideHungerIcon(EntityUid uid, HungerComponent hungerComponent)
{
var result = new List<StatusIconPrototype>();
switch (hungerComponent.CurrentThreshold)
{
case HungerThreshold.Overfed:
if (_prototypeMan.TryIndex<StatusIconPrototype>("HungerIconOverfed", out var overfed))
{
result.Add(overfed);
}
break;
case HungerThreshold.Peckish:
if (_prototypeMan.TryIndex<StatusIconPrototype>("HungerIconPeckish", out var peckish))
{
result.Add(peckish);
}
break;
case HungerThreshold.Starving:
if (_prototypeMan.TryIndex<StatusIconPrototype>("HungerIconStarving", out var starving))
{
result.Add(starving);
}
break;
}
return result;
if (_hunger.TryGetStatusIconPrototype(component, out var iconPrototype))
ev.StatusIcons.Add(iconPrototype);
}
}

View File

@@ -0,0 +1,60 @@
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Overlays;
using Content.Shared.PDA;
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Shared.Prototypes;
namespace Content.Client.Overlays;
public sealed class ShowJobIconsSystem : EquipmentHudSystem<ShowJobIconsComponent>
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
[ValidatePrototypeId<StatusIconPrototype>]
private const string JobIconForNoId = "JobIconNoId";
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StatusIconComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
}
private void OnGetStatusIconsEvent(EntityUid uid, StatusIconComponent _, ref GetStatusIconsEvent ev)
{
if (!IsActive || ev.InContainer)
return;
var iconId = JobIconForNoId;
if (_accessReader.FindAccessItemsInventory(uid, out var items))
{
foreach (var item in items)
{
// ID Card
if (TryComp<IdCardComponent>(item, out var id))
{
iconId = id.JobIcon;
break;
}
// PDA
if (TryComp<PdaComponent>(item, out var pda)
&& pda.ContainedId != null
&& TryComp(pda.ContainedId, out id))
{
iconId = id.JobIcon;
break;
}
}
}
if (_prototype.TryIndex<StatusIconPrototype>(iconId, out var iconPrototype))
ev.StatusIcons.Add(iconPrototype);
else
Log.Error($"Invalid job icon prototype: {iconPrototype}");
}
}

View File

@@ -0,0 +1,28 @@
using Content.Shared.Mindshield.Components;
using Content.Shared.Overlays;
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Shared.Prototypes;
namespace Content.Client.Overlays;
public sealed class ShowMindShieldIconsSystem : EquipmentHudSystem<ShowMindShieldIconsComponent>
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MindShieldComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
}
private void OnGetStatusIconsEvent(EntityUid uid, MindShieldComponent component, ref GetStatusIconsEvent ev)
{
if (!IsActive || ev.InContainer)
return;
if (_prototype.TryIndex<StatusIconPrototype>(component.MindShieldStatusIcon.Id, out var iconPrototype))
ev.StatusIcons.Add(iconPrototype);
}
}

View File

@@ -1,86 +0,0 @@
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Mindshield.Components;
using Content.Shared.Overlays;
using Content.Shared.PDA;
using Content.Shared.Security.Components;
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Shared.Prototypes;
namespace Content.Client.Overlays;
public sealed class ShowSecurityIconsSystem : EquipmentHudSystem<ShowSecurityIconsComponent>
{
[Dependency] private readonly IPrototypeManager _prototypeMan = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
[ValidatePrototypeId<StatusIconPrototype>]
private const string JobIconForNoId = "JobIconNoId";
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StatusIconComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
}
private void OnGetStatusIconsEvent(EntityUid uid, StatusIconComponent _, ref GetStatusIconsEvent @event)
{
if (!IsActive || @event.InContainer)
{
return;
}
var securityIcons = DecideSecurityIcon(uid);
@event.StatusIcons.AddRange(securityIcons);
}
private IReadOnlyList<StatusIconPrototype> DecideSecurityIcon(EntityUid uid)
{
var result = new List<StatusIconPrototype>();
var jobIconToGet = JobIconForNoId;
if (_accessReader.FindAccessItemsInventory(uid, out var items))
{
foreach (var item in items)
{
// ID Card
if (TryComp(item, out IdCardComponent? id))
{
jobIconToGet = id.JobIcon;
break;
}
// PDA
if (TryComp(item, out PdaComponent? pda)
&& pda.ContainedId != null
&& TryComp(pda.ContainedId, out id))
{
jobIconToGet = id.JobIcon;
break;
}
}
}
if (_prototypeMan.TryIndex<StatusIconPrototype>(jobIconToGet, out var jobIcon))
result.Add(jobIcon);
else
Log.Error($"Invalid job icon prototype: {jobIcon}");
if (TryComp<MindShieldComponent>(uid, out var comp))
{
if (_prototypeMan.TryIndex<StatusIconPrototype>(comp.MindShieldStatusIcon.Id, out var icon))
result.Add(icon);
}
if (TryComp<CriminalRecordComponent>(uid, out var record))
{
if(_prototypeMan.TryIndex<StatusIconPrototype>(record.StatusIcon.Id, out var criminalIcon))
result.Add(criminalIcon);
}
return result;
}
}

View File

@@ -1,10 +1,11 @@
using Content.Shared.Overlays;
using Content.Shared.StatusIcon.Components;
using Content.Shared.NukeOps;
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Shared.Prototypes;
namespace Content.Client.Overlays;
public sealed class ShowSyndicateIconsSystem : EquipmentHudSystem<ShowSyndicateIconsComponent>
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
@@ -16,28 +17,13 @@ public sealed class ShowSyndicateIconsSystem : EquipmentHudSystem<ShowSyndicateI
SubscribeLocalEvent<NukeOperativeComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
}
private void OnGetStatusIconsEvent(EntityUid uid, NukeOperativeComponent nukeOperativeComponent, ref GetStatusIconsEvent args)
private void OnGetStatusIconsEvent(EntityUid uid, NukeOperativeComponent component, ref GetStatusIconsEvent ev)
{
if (!IsActive || args.InContainer)
{
if (!IsActive || ev.InContainer)
return;
}
var syndicateIcons = SyndicateIcon(uid, nukeOperativeComponent);
args.StatusIcons.AddRange(syndicateIcons);
}
private IReadOnlyList<StatusIconPrototype> SyndicateIcon(EntityUid uid, NukeOperativeComponent nukeOperativeComponent)
{
var result = new List<StatusIconPrototype>();
if (_prototype.TryIndex<StatusIconPrototype>(nukeOperativeComponent.SyndStatusIcon, out var syndicateicon))
{
result.Add(syndicateicon);
}
return result;
if (_prototype.TryIndex<StatusIconPrototype>(component.SyndStatusIcon, out var iconPrototype))
ev.StatusIcons.Add(iconPrototype);
}
}

View File

@@ -1,14 +1,13 @@
using Content.Shared.Nutrition.EntitySystems;
using Content.Shared.Nutrition.Components;
using Content.Shared.Overlays;
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Shared.Prototypes;
namespace Content.Client.Overlays;
public sealed class ShowThirstIconsSystem : EquipmentHudSystem<ShowThirstIconsComponent>
{
[Dependency] private readonly IPrototypeManager _prototypeMan = default!;
[Dependency] private readonly ThirstSystem _thirst = default!;
public override void Initialize()
{
@@ -17,42 +16,12 @@ public sealed class ShowThirstIconsSystem : EquipmentHudSystem<ShowThirstIconsCo
SubscribeLocalEvent<ThirstComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
}
private void OnGetStatusIconsEvent(EntityUid uid, ThirstComponent thirstComponent, ref GetStatusIconsEvent args)
private void OnGetStatusIconsEvent(EntityUid uid, ThirstComponent component, ref GetStatusIconsEvent ev)
{
if (!IsActive || args.InContainer)
if (!IsActive || ev.InContainer)
return;
var thirstIcons = DecideThirstIcon(uid, thirstComponent);
args.StatusIcons.AddRange(thirstIcons);
}
private IReadOnlyList<StatusIconPrototype> DecideThirstIcon(EntityUid uid, ThirstComponent thirstComponent)
{
var result = new List<StatusIconPrototype>();
switch (thirstComponent.CurrentThirstThreshold)
{
case ThirstThreshold.OverHydrated:
if (_prototypeMan.TryIndex<StatusIconPrototype>("ThirstIconOverhydrated", out var overhydrated))
{
result.Add(overhydrated);
}
break;
case ThirstThreshold.Thirsty:
if (_prototypeMan.TryIndex<StatusIconPrototype>("ThirstIconThirsty", out var thirsty))
{
result.Add(thirsty);
}
break;
case ThirstThreshold.Parched:
if (_prototypeMan.TryIndex<StatusIconPrototype>("ThirstIconParched", out var parched))
{
result.Add(parched);
}
break;
}
return result;
if (_thirst.TryGetStatusIconPrototype(component, out var iconPrototype))
ev.StatusIcons.Add(iconPrototype!);
}
}

View File

@@ -21,7 +21,6 @@ namespace Content.Client.PDA
protected override void Open()
{
base.Open();
SendMessage(new PdaRequestUpdateInterfaceMessage());
_menu = new PdaMenu();
_menu.OpenCenteredLeft();
_menu.OnClose += Close;
@@ -32,17 +31,17 @@ namespace Content.Client.PDA
_menu.EjectIdButton.OnPressed += _ =>
{
SendMessage(new ItemSlotButtonPressedEvent(PdaComponent.PdaIdSlotId));
SendPredictedMessage(new ItemSlotButtonPressedEvent(PdaComponent.PdaIdSlotId));
};
_menu.EjectPenButton.OnPressed += _ =>
{
SendMessage(new ItemSlotButtonPressedEvent(PdaComponent.PdaPenSlotId));
SendPredictedMessage(new ItemSlotButtonPressedEvent(PdaComponent.PdaPenSlotId));
};
_menu.EjectPaiButton.OnPressed += _ =>
{
SendMessage(new ItemSlotButtonPressedEvent(PdaComponent.PdaPaiSlotId));
SendPredictedMessage(new ItemSlotButtonPressedEvent(PdaComponent.PdaPaiSlotId));
};
_menu.ActivateMusicButton.OnPressed += _ =>

View File

@@ -1,9 +1,6 @@
using Content.Shared.Paper;
using Robust.Shared.GameStates;
namespace Content.Client.Paper;
[NetworkedComponent, RegisterComponent]
public sealed partial class PaperComponent : SharedPaperComponent
{
}
[RegisterComponent]
public sealed partial class PaperComponent : SharedPaperComponent;

View File

@@ -1,18 +1,14 @@
using System.Numerics;
using Content.Shared.Pinpointer;
using Robust.Client.Graphics;
using Robust.Shared.Enums;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
namespace Content.Client.Pinpointer;
public sealed class NavMapSystem : SharedNavMapSystem
public sealed partial class NavMapSystem : SharedNavMapSystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<NavMapComponent, ComponentHandleState>(OnHandleState);
}
@@ -21,89 +17,34 @@ public sealed class NavMapSystem : SharedNavMapSystem
if (args.Current is not NavMapComponentState state)
return;
component.Chunks.Clear();
foreach (var (origin, data) in state.TileData)
if (!state.FullState)
{
component.Chunks.Add(origin, new NavMapChunk(origin)
foreach (var index in component.Chunks.Keys)
{
TileData = data,
});
if (!state.AllChunks!.Contains(index))
component.Chunks.Remove(index);
}
}
component.Beacons.Clear();
component.Beacons.AddRange(state.Beacons);
component.Airlocks.Clear();
component.Airlocks.AddRange(state.Airlocks);
}
}
public sealed class NavMapOverlay : Overlay
{
private readonly IEntityManager _entManager;
private readonly IMapManager _mapManager;
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private List<Entity<MapGridComponent>> _grids = new();
public NavMapOverlay(IEntityManager entManager, IMapManager mapManager)
{
_entManager = entManager;
_mapManager = mapManager;
}
protected override void Draw(in OverlayDrawArgs args)
{
var query = _entManager.GetEntityQuery<NavMapComponent>();
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
var scale = Matrix3.CreateScale(new Vector2(1f, 1f));
_grids.Clear();
_mapManager.FindGridsIntersecting(args.MapId, args.WorldBounds, ref _grids);
foreach (var grid in _grids)
else
{
if (!query.TryGetComponent(grid, out var navMap) || !xformQuery.TryGetComponent(grid.Owner, out var xform))
continue;
// TODO: Faster helper method
var (_, _, matrix, invMatrix) = xform.GetWorldPositionRotationMatrixWithInv();
var localAABB = invMatrix.TransformBox(args.WorldBounds);
Matrix3.Multiply(in scale, in matrix, out var matty);
args.WorldHandle.SetTransform(matty);
for (var x = Math.Floor(localAABB.Left); x <= Math.Ceiling(localAABB.Right); x += SharedNavMapSystem.ChunkSize * grid.Comp.TileSize)
foreach (var index in component.Chunks.Keys)
{
for (var y = Math.Floor(localAABB.Bottom); y <= Math.Ceiling(localAABB.Top); y += SharedNavMapSystem.ChunkSize * grid.Comp.TileSize)
{
var floored = new Vector2i((int) x, (int) y);
var chunkOrigin = SharedMapSystem.GetChunkIndices(floored, SharedNavMapSystem.ChunkSize);
if (!navMap.Chunks.TryGetValue(chunkOrigin, out var chunk))
continue;
// TODO: Okay maybe I should just use ushorts lmao...
for (var i = 0; i < SharedNavMapSystem.ChunkSize * SharedNavMapSystem.ChunkSize; i++)
{
var value = (int) Math.Pow(2, i);
var mask = chunk.TileData & value;
if (mask == 0x0)
continue;
var tile = chunk.Origin * SharedNavMapSystem.ChunkSize + SharedNavMapSystem.GetTile(mask);
args.WorldHandle.DrawRect(new Box2(tile * grid.Comp.TileSize, (tile + 1) * grid.Comp.TileSize), Color.Aqua, false);
}
}
if (!state.Chunks.ContainsKey(index))
component.Chunks.Remove(index);
}
}
args.WorldHandle.SetTransform(Matrix3.Identity);
foreach (var (origin, chunk) in state.Chunks)
{
var newChunk = new NavMapChunk(origin);
Array.Copy(chunk, newChunk.TileData, chunk.Length);
component.Chunks[origin] = newChunk;
}
component.Beacons.Clear();
foreach (var (nuid, beacon) in state.Beacons)
{
component.Beacons[nuid] = beacon;
}
}
}

View File

@@ -16,6 +16,9 @@ using Robust.Shared.Physics.Components;
using Robust.Shared.Timing;
using System.Numerics;
using JetBrains.Annotations;
using Content.Shared.Atmos;
using System.Linq;
using Robust.Shared.Utility;
namespace Content.Client.Pinpointer.UI;
@@ -27,6 +30,7 @@ public partial class NavMapControl : MapGridControl
{
[Dependency] private IResourceCache _cache = default!;
private readonly SharedTransformSystem _transformSystem;
private readonly SharedNavMapSystem _navMapSystem;
public EntityUid? Owner;
public EntityUid? MapUid;
@@ -40,7 +44,10 @@ public partial class NavMapControl : MapGridControl
// Tracked data
public Dictionary<EntityCoordinates, (bool Visible, Color Color)> TrackedCoordinates = new();
public Dictionary<NetEntity, NavMapBlip> TrackedEntities = new();
public Dictionary<Vector2i, List<NavMapLine>>? TileGrid = default!;
public List<(Vector2, Vector2)> TileLines = new();
public List<(Vector2, Vector2)> TileRects = new();
public List<(Vector2[], Color)> TilePolygons = new();
// Default colors
public Color WallColor = new(102, 217, 102);
@@ -53,14 +60,23 @@ public partial class NavMapControl : MapGridControl
protected static float MinDisplayedRange = 8f;
protected static float MaxDisplayedRange = 128f;
protected static float DefaultDisplayedRange = 48f;
protected float MinmapScaleModifier = 0.075f;
protected float FullWallInstep = 0.165f;
protected float ThinWallThickness = 0.165f;
protected float ThinDoorThickness = 0.30f;
// Local variables
private float _updateTimer = 0.25f;
private float _updateTimer = 1.0f;
private Dictionary<Color, Color> _sRGBLookUp = new();
protected Color BackgroundColor;
protected float BackgroundOpacity = 0.9f;
private int _targetFontsize = 8;
private Dictionary<Vector2i, Vector2i> _horizLines = new();
private Dictionary<Vector2i, Vector2i> _horizLinesReversed = new();
private Dictionary<Vector2i, Vector2i> _vertLines = new();
private Dictionary<Vector2i, Vector2i> _vertLinesReversed = new();
// Components
private NavMapComponent? _navMap;
private MapGridComponent? _grid;
@@ -72,6 +88,7 @@ public partial class NavMapControl : MapGridControl
private readonly Label _zoom = new()
{
VerticalAlignment = VAlignment.Top,
HorizontalExpand = true,
Margin = new Thickness(8f, 8f),
};
@@ -80,6 +97,7 @@ public partial class NavMapControl : MapGridControl
Text = Loc.GetString("navmap-recenter"),
VerticalAlignment = VAlignment.Top,
HorizontalAlignment = HAlignment.Right,
HorizontalExpand = true,
Margin = new Thickness(8f, 4f),
Disabled = true,
};
@@ -87,9 +105,10 @@ public partial class NavMapControl : MapGridControl
private readonly CheckBox _beacons = new()
{
Text = Loc.GetString("navmap-toggle-beacons"),
Margin = new Thickness(4f, 0f),
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center,
HorizontalExpand = true,
Margin = new Thickness(4f, 0f),
Pressed = true,
};
@@ -98,6 +117,8 @@ public partial class NavMapControl : MapGridControl
IoCManager.InjectDependencies(this);
_transformSystem = EntManager.System<SharedTransformSystem>();
_navMapSystem = EntManager.System<SharedNavMapSystem>();
BackgroundColor = Color.FromSrgb(TileColor.WithAlpha(BackgroundOpacity));
RectClipContent = true;
@@ -112,6 +133,8 @@ public partial class NavMapControl : MapGridControl
BorderColor = StyleNano.PanelDark
},
VerticalExpand = false,
HorizontalExpand = true,
SetWidth = 650f,
Children =
{
new BoxContainer()
@@ -130,6 +153,7 @@ public partial class NavMapControl : MapGridControl
var topContainer = new BoxContainer()
{
Orientation = BoxContainer.LayoutOrientation.Vertical,
HorizontalExpand = true,
Children =
{
topPanel,
@@ -157,6 +181,9 @@ public partial class NavMapControl : MapGridControl
{
EntManager.TryGetComponent(MapUid, out _navMap);
EntManager.TryGetComponent(MapUid, out _grid);
EntManager.TryGetComponent(MapUid, out _xform);
EntManager.TryGetComponent(MapUid, out _physics);
EntManager.TryGetComponent(MapUid, out _fixtures);
UpdateNavMap();
}
@@ -251,119 +278,93 @@ public partial class NavMapControl : MapGridControl
EntManager.TryGetComponent(MapUid, out _physics);
EntManager.TryGetComponent(MapUid, out _fixtures);
if (_navMap == null || _grid == null || _xform == null)
return;
// Map re-centering
_recenter.Disabled = DrawRecenter();
_zoom.Text = Loc.GetString("navmap-zoom", ("value", $"{(DefaultDisplayedRange / WorldRange ):0.0}"));
if (_navMap == null || _xform == null)
return;
// Update zoom text
_zoom.Text = Loc.GetString("navmap-zoom", ("value", $"{(DefaultDisplayedRange / WorldRange):0.0}"));
// Update offset with physics local center
var offset = Offset;
if (_physics != null)
offset += _physics.LocalCenter;
// Draw tiles
if (_fixtures != null)
var offsetVec = new Vector2(offset.X, -offset.Y);
// Wall sRGB
if (!_sRGBLookUp.TryGetValue(WallColor, out var wallsRGB))
{
wallsRGB = Color.ToSrgb(WallColor);
_sRGBLookUp[WallColor] = wallsRGB;
}
// Draw floor tiles
if (TilePolygons.Any())
{
Span<Vector2> verts = new Vector2[8];
foreach (var fixture in _fixtures.Fixtures.Values)
foreach (var (polygonVerts, polygonColor) in TilePolygons)
{
if (fixture.Shape is not PolygonShape poly)
continue;
for (var i = 0; i < poly.VertexCount; i++)
for (var i = 0; i < polygonVerts.Length; i++)
{
var vert = poly.Vertices[i] - offset;
var vert = polygonVerts[i] - offset;
verts[i] = ScalePosition(new Vector2(vert.X, -vert.Y));
}
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, verts[..poly.VertexCount], TileColor);
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, verts[..polygonVerts.Length], polygonColor);
}
}
var area = new Box2(-WorldRange, -WorldRange, WorldRange + 1f, WorldRange + 1f).Translated(offset);
// Drawing lines can be rather expensive due to the number of neighbors that need to be checked in order
// to figure out where they should be drawn. However, we don't *need* to do check these every frame.
// Instead, lets periodically update where to draw each line and then store these points in a list.
// Then we can just run through the list each frame and draw the lines without any extra computation.
// Draw walls
if (TileGrid != null && TileGrid.Count > 0)
// Draw map lines
if (TileLines.Any())
{
var walls = new ValueList<Vector2>();
var lines = new ValueList<Vector2>(TileLines.Count * 2);
foreach ((var chunk, var chunkedLines) in TileGrid)
foreach (var (o, t) in TileLines)
{
var offsetChunk = new Vector2(chunk.X, chunk.Y) * SharedNavMapSystem.ChunkSize;
var origin = ScalePosition(o - offsetVec);
var terminus = ScalePosition(t - offsetVec);
if (offsetChunk.X < area.Left - SharedNavMapSystem.ChunkSize || offsetChunk.X > area.Right)
continue;
if (offsetChunk.Y < area.Bottom - SharedNavMapSystem.ChunkSize || offsetChunk.Y > area.Top)
continue;
foreach (var chunkedLine in chunkedLines)
{
var start = ScalePosition(chunkedLine.Origin - new Vector2(offset.X, -offset.Y));
var end = ScalePosition(chunkedLine.Terminus - new Vector2(offset.X, -offset.Y));
walls.Add(start);
walls.Add(end);
}
lines.Add(origin);
lines.Add(terminus);
}
if (walls.Count > 0)
{
if (!_sRGBLookUp.TryGetValue(WallColor, out var sRGB))
{
sRGB = Color.ToSrgb(WallColor);
_sRGBLookUp[WallColor] = sRGB;
}
handle.DrawPrimitives(DrawPrimitiveTopology.LineList, walls.Span, sRGB);
}
if (lines.Count > 0)
handle.DrawPrimitives(DrawPrimitiveTopology.LineList, lines.Span, wallsRGB);
}
var airlockBuffer = Vector2.One * (MinimapScale / 2.25f) * 0.75f;
var airlockLines = new ValueList<Vector2>();
var foobarVec = new Vector2(1, -1);
foreach (var airlock in _navMap.Airlocks)
// Draw map rects
if (TileRects.Any())
{
var position = airlock.Position - offset;
position = ScalePosition(position with { Y = -position.Y });
airlockLines.Add(position + airlockBuffer);
airlockLines.Add(position - airlockBuffer * foobarVec);
var rects = new ValueList<Vector2>(TileRects.Count * 8);
airlockLines.Add(position + airlockBuffer);
airlockLines.Add(position + airlockBuffer * foobarVec);
airlockLines.Add(position - airlockBuffer);
airlockLines.Add(position + airlockBuffer * foobarVec);
airlockLines.Add(position - airlockBuffer);
airlockLines.Add(position - airlockBuffer * foobarVec);
airlockLines.Add(position + airlockBuffer * -Vector2.UnitY);
airlockLines.Add(position - airlockBuffer * -Vector2.UnitY);
}
if (airlockLines.Count > 0)
{
if (!_sRGBLookUp.TryGetValue(WallColor, out var sRGB))
foreach (var (lt, rb) in TileRects)
{
sRGB = Color.ToSrgb(WallColor);
_sRGBLookUp[WallColor] = sRGB;
var leftTop = ScalePosition(lt - offsetVec);
var rightBottom = ScalePosition(rb - offsetVec);
var rightTop = new Vector2(rightBottom.X, leftTop.Y);
var leftBottom = new Vector2(leftTop.X, rightBottom.Y);
rects.Add(leftTop);
rects.Add(rightTop);
rects.Add(rightTop);
rects.Add(rightBottom);
rects.Add(rightBottom);
rects.Add(leftBottom);
rects.Add(leftBottom);
rects.Add(leftTop);
}
handle.DrawPrimitives(DrawPrimitiveTopology.LineList, airlockLines.Span, sRGB);
if (rects.Count > 0)
handle.DrawPrimitives(DrawPrimitiveTopology.LineList, rects.Span, wallsRGB);
}
// Invoke post wall drawing action
if (PostWallDrawingAction != null)
PostWallDrawingAction.Invoke(handle);
@@ -373,10 +374,10 @@ public partial class NavMapControl : MapGridControl
var rectBuffer = new Vector2(5f, 3f);
// Calculate font size for current zoom level
var fontSize = (int) Math.Round(1 / WorldRange * DefaultDisplayedRange * UIScale * _targetFontsize , 0);
var fontSize = (int) Math.Round(1 / WorldRange * DefaultDisplayedRange * UIScale * _targetFontsize, 0);
var font = new VectorFont(_cache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Bold.ttf"), fontSize);
foreach (var beacon in _navMap.Beacons)
foreach (var beacon in _navMap.Beacons.Values)
{
var position = beacon.Position - offset;
position = ScalePosition(position with { Y = -position.Y });
@@ -409,8 +410,6 @@ public partial class NavMapControl : MapGridControl
}
// Tracked entities (can use a supplied sprite as a marker instead; should probably just replace TrackedCoordinates with this eventually)
var iconVertexUVs = new Dictionary<(Texture, Color), ValueList<DrawVertexUV2D>>();
foreach (var blip in TrackedEntities.Values)
{
if (blip.Blinks && !lit)
@@ -419,9 +418,6 @@ public partial class NavMapControl : MapGridControl
if (blip.Texture == null)
continue;
if (!iconVertexUVs.TryGetValue((blip.Texture, blip.Color), out var vertexUVs))
vertexUVs = new();
var mapPos = blip.Coordinates.ToMap(EntManager, _transformSystem);
if (mapPos.MapId != MapId.Nullspace)
@@ -429,29 +425,11 @@ public partial class NavMapControl : MapGridControl
var position = _transformSystem.GetInvWorldMatrix(_xform).Transform(mapPos.Position) - offset;
position = ScalePosition(new Vector2(position.X, -position.Y));
var scalingCoefficient = 2.5f;
var positionOffset = scalingCoefficient * float.Sqrt(MinimapScale);
var scalingCoefficient = MinmapScaleModifier * float.Sqrt(MinimapScale);
var positionOffset = new Vector2(scalingCoefficient * blip.Texture.Width, scalingCoefficient * blip.Texture.Height);
vertexUVs.Add(new DrawVertexUV2D(new Vector2(position.X - positionOffset, position.Y - positionOffset), new Vector2(1f, 1f)));
vertexUVs.Add(new DrawVertexUV2D(new Vector2(position.X - positionOffset, position.Y + positionOffset), new Vector2(1f, 0f)));
vertexUVs.Add(new DrawVertexUV2D(new Vector2(position.X + positionOffset, position.Y - positionOffset), new Vector2(0f, 1f)));
vertexUVs.Add(new DrawVertexUV2D(new Vector2(position.X - positionOffset, position.Y + positionOffset), new Vector2(1f, 0f)));
vertexUVs.Add(new DrawVertexUV2D(new Vector2(position.X + positionOffset, position.Y - positionOffset), new Vector2(0f, 1f)));
vertexUVs.Add(new DrawVertexUV2D(new Vector2(position.X + positionOffset, position.Y + positionOffset), new Vector2(0f, 0f)));
handle.DrawTextureRect(blip.Texture, new UIBox2(position - positionOffset, position + positionOffset), blip.Color);
}
iconVertexUVs[(blip.Texture, blip.Color)] = vertexUVs;
}
foreach ((var (texture, color), var vertexUVs) in iconVertexUVs)
{
if (!_sRGBLookUp.TryGetValue(color, out var sRGB))
{
sRGB = Color.ToSrgb(color);
_sRGBLookUp[color] = sRGB;
}
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleList, texture, vertexUVs.Span, sRGB);
}
}
@@ -469,124 +447,266 @@ public partial class NavMapControl : MapGridControl
}
protected virtual void UpdateNavMap()
{
// Clear stale values
TilePolygons.Clear();
TileLines.Clear();
TileRects.Clear();
UpdateNavMapFloorTiles();
UpdateNavMapWallLines();
UpdateNavMapAirlocks();
}
private void UpdateNavMapFloorTiles()
{
if (_fixtures == null)
return;
var verts = new Vector2[8];
foreach (var fixture in _fixtures.Fixtures.Values)
{
if (fixture.Shape is not PolygonShape poly)
continue;
for (var i = 0; i < poly.VertexCount; i++)
{
var vert = poly.Vertices[i];
verts[i] = new Vector2(MathF.Round(vert.X), MathF.Round(vert.Y));
}
TilePolygons.Add((verts[..poly.VertexCount], TileColor));
}
}
private void UpdateNavMapWallLines()
{
if (_navMap == null || _grid == null)
return;
TileGrid = GetDecodedWallChunks(_navMap.Chunks, _grid);
}
// We'll use the following dictionaries to combine collinear wall lines
_horizLines.Clear();
_horizLinesReversed.Clear();
_vertLines.Clear();
_vertLinesReversed.Clear();
public Dictionary<Vector2i, List<NavMapLine>> GetDecodedWallChunks
(Dictionary<Vector2i, NavMapChunk> chunks,
MapGridComponent grid)
{
var decodedOutput = new Dictionary<Vector2i, List<NavMapLine>>();
const int southMask = (int) AtmosDirection.South << (int) NavMapChunkType.Wall;
const int eastMask = (int) AtmosDirection.East << (int) NavMapChunkType.Wall;
const int westMask = (int) AtmosDirection.West << (int) NavMapChunkType.Wall;
const int northMask = (int) AtmosDirection.North << (int) NavMapChunkType.Wall;
foreach ((var chunkOrigin, var chunk) in chunks)
foreach (var (chunkOrigin, chunk) in _navMap.Chunks)
{
var list = new List<NavMapLine>();
// TODO: Okay maybe I should just use ushorts lmao...
for (var i = 0; i < SharedNavMapSystem.ChunkSize * SharedNavMapSystem.ChunkSize; i++)
for (var i = 0; i < SharedNavMapSystem.ArraySize; i++)
{
var value = (int) Math.Pow(2, i);
var mask = chunk.TileData & value;
if (mask == 0x0)
var tileData = chunk.TileData[i] & SharedNavMapSystem.WallMask;
if (tileData == 0)
continue;
// Alright now we'll work out our edges
var relativeTile = SharedNavMapSystem.GetTile(mask);
var tile = (chunk.Origin * SharedNavMapSystem.ChunkSize + relativeTile) * grid.TileSize;
var position = new Vector2(tile.X, -tile.Y);
tileData >>= (int) NavMapChunkType.Wall;
var relativeTile = SharedNavMapSystem.GetTileFromIndex(i);
var tile = (chunk.Origin * SharedNavMapSystem.ChunkSize + relativeTile) * _grid.TileSize;
if (tileData != SharedNavMapSystem.AllDirMask)
{
AddRectForThinWall(tileData, tile);
continue;
}
tile = tile with { Y = -tile.Y };
NavMapChunk? neighborChunk;
bool neighbor;
// North edge
if (relativeTile.Y == SharedNavMapSystem.ChunkSize - 1)
{
neighbor = chunks.TryGetValue(chunkOrigin + new Vector2i(0, 1), out neighborChunk) &&
(neighborChunk.TileData &
SharedNavMapSystem.GetFlag(new Vector2i(relativeTile.X, 0))) != 0x0;
}
else
{
var flag = SharedNavMapSystem.GetFlag(relativeTile + new Vector2i(0, 1));
neighbor = (chunk.TileData & flag) != 0x0;
}
var neighborData = 0;
if (relativeTile.Y != SharedNavMapSystem.ChunkSize - 1)
neighborData = chunk.TileData[i+1];
else if (_navMap.Chunks.TryGetValue(chunkOrigin + Vector2i.Up, out neighborChunk))
neighborData = neighborChunk.TileData[i + 1 - SharedNavMapSystem.ChunkSize];
if (!neighbor)
if ((neighborData & southMask) == 0)
{
// Add points
list.Add(new NavMapLine(position + new Vector2(0f, -grid.TileSize), position + new Vector2(grid.TileSize, -grid.TileSize)));
AddOrUpdateNavMapLine(tile + new Vector2i(0, -_grid.TileSize),
tile + new Vector2i(_grid.TileSize, -_grid.TileSize), _horizLines,
_horizLinesReversed);
}
// East edge
if (relativeTile.X == SharedNavMapSystem.ChunkSize - 1)
{
neighbor = chunks.TryGetValue(chunkOrigin + new Vector2i(1, 0), out neighborChunk) &&
(neighborChunk.TileData &
SharedNavMapSystem.GetFlag(new Vector2i(0, relativeTile.Y))) != 0x0;
}
else
{
var flag = SharedNavMapSystem.GetFlag(relativeTile + new Vector2i(1, 0));
neighbor = (chunk.TileData & flag) != 0x0;
}
neighborData = 0;
if (relativeTile.X != SharedNavMapSystem.ChunkSize - 1)
neighborData = chunk.TileData[i+SharedNavMapSystem.ChunkSize];
else if (_navMap.Chunks.TryGetValue(chunkOrigin + Vector2i.Right, out neighborChunk))
neighborData = neighborChunk.TileData[i + SharedNavMapSystem.ChunkSize - SharedNavMapSystem.ArraySize];
if (!neighbor)
if ((neighborData & westMask) == 0)
{
// Add points
list.Add(new NavMapLine(position + new Vector2(grid.TileSize, -grid.TileSize), position + new Vector2(grid.TileSize, 0f)));
AddOrUpdateNavMapLine(tile + new Vector2i(_grid.TileSize, -_grid.TileSize),
tile + new Vector2i(_grid.TileSize, 0), _vertLines, _vertLinesReversed);
}
// South edge
if (relativeTile.Y == 0)
{
neighbor = chunks.TryGetValue(chunkOrigin + new Vector2i(0, -1), out neighborChunk) &&
(neighborChunk.TileData &
SharedNavMapSystem.GetFlag(new Vector2i(relativeTile.X, SharedNavMapSystem.ChunkSize - 1))) != 0x0;
}
else
{
var flag = SharedNavMapSystem.GetFlag(relativeTile + new Vector2i(0, -1));
neighbor = (chunk.TileData & flag) != 0x0;
}
neighborData = 0;
if (relativeTile.Y != 0)
neighborData = chunk.TileData[i-1];
else if (_navMap.Chunks.TryGetValue(chunkOrigin + Vector2i.Down, out neighborChunk))
neighborData = neighborChunk.TileData[i - 1 + SharedNavMapSystem.ChunkSize];
if (!neighbor)
if ((neighborData & northMask) == 0)
{
// Add points
list.Add(new NavMapLine(position + new Vector2(grid.TileSize, 0f), position));
AddOrUpdateNavMapLine(tile, tile + new Vector2i(_grid.TileSize, 0), _horizLines,
_horizLinesReversed);
}
// West edge
if (relativeTile.X == 0)
neighborData = 0;
if (relativeTile.X != 0)
neighborData = chunk.TileData[i-SharedNavMapSystem.ChunkSize];
else if (_navMap.Chunks.TryGetValue(chunkOrigin + Vector2i.Left, out neighborChunk))
neighborData = neighborChunk.TileData[i - SharedNavMapSystem.ChunkSize + SharedNavMapSystem.ArraySize];
if ((neighborData & eastMask) == 0)
{
neighbor = chunks.TryGetValue(chunkOrigin + new Vector2i(-1, 0), out neighborChunk) &&
(neighborChunk.TileData &
SharedNavMapSystem.GetFlag(new Vector2i(SharedNavMapSystem.ChunkSize - 1, relativeTile.Y))) != 0x0;
}
else
{
var flag = SharedNavMapSystem.GetFlag(relativeTile + new Vector2i(-1, 0));
neighbor = (chunk.TileData & flag) != 0x0;
AddOrUpdateNavMapLine(tile + new Vector2i(0, -_grid.TileSize), tile, _vertLines,
_vertLinesReversed);
}
if (!neighbor)
{
// Add point
list.Add(new NavMapLine(position, position + new Vector2(0f, -grid.TileSize)));
}
// Draw a diagonal line for interiors.
list.Add(new NavMapLine(position + new Vector2(0f, -grid.TileSize), position + new Vector2(grid.TileSize, 0f)));
// Add a diagonal line for interiors. Unless there are a lot of double walls, there is no point combining these
TileLines.Add((tile + new Vector2(0, -_grid.TileSize), tile + new Vector2(_grid.TileSize, 0)));
}
decodedOutput.Add(chunkOrigin, list);
}
return decodedOutput;
// Record the combined lines
foreach (var (origin, terminal) in _horizLines)
{
TileLines.Add((origin, terminal));
}
foreach (var (origin, terminal) in _vertLines)
{
TileLines.Add((origin, terminal));
}
}
private void UpdateNavMapAirlocks()
{
if (_navMap == null || _grid == null)
return;
foreach (var chunk in _navMap.Chunks.Values)
{
for (var i = 0; i < SharedNavMapSystem.ArraySize; i++)
{
var tileData = chunk.TileData[i] & SharedNavMapSystem.AirlockMask;
if (tileData == 0)
continue;
tileData >>= (int) NavMapChunkType.Airlock;
var relative = SharedNavMapSystem.GetTileFromIndex(i);
var tile = (chunk.Origin * SharedNavMapSystem.ChunkSize + relative) * _grid.TileSize;
// If the edges of an airlock tile are not all occupied, draw a thin airlock for each edge
if (tileData != SharedNavMapSystem.AllDirMask)
{
AddRectForThinAirlock(tileData, tile);
continue;
}
// Otherwise add a single full tile airlock
TileRects.Add((new Vector2(tile.X + FullWallInstep, -tile.Y - FullWallInstep),
new Vector2(tile.X - FullWallInstep + 1f, -tile.Y + FullWallInstep - 1)));
TileLines.Add((new Vector2(tile.X + 0.5f, -tile.Y - FullWallInstep),
new Vector2(tile.X + 0.5f, -tile.Y + FullWallInstep - 1)));
}
}
}
private void AddRectForThinWall(int tileData, Vector2i tile)
{
var leftTop = new Vector2(-0.5f, 0.5f - ThinWallThickness);
var rightBottom = new Vector2(0.5f, 0.5f);
for (var i = 0; i < SharedNavMapSystem.Directions; i++)
{
var dirMask = 1 << i;
if ((tileData & dirMask) == 0)
continue;
var tilePosition = new Vector2(tile.X + 0.5f, -tile.Y - 0.5f);
// TODO NAVMAP
// Consider using faster rotation operations, given that these are always 90 degree increments
var angle = -((AtmosDirection) dirMask).ToAngle();
TileRects.Add((angle.RotateVec(leftTop) + tilePosition, angle.RotateVec(rightBottom) + tilePosition));
}
}
private void AddRectForThinAirlock(int tileData, Vector2i tile)
{
var leftTop = new Vector2(-0.5f + FullWallInstep, 0.5f - FullWallInstep - ThinDoorThickness);
var rightBottom = new Vector2(0.5f - FullWallInstep, 0.5f - FullWallInstep);
var centreTop = new Vector2(0f, 0.5f - FullWallInstep - ThinDoorThickness);
var centreBottom = new Vector2(0f, 0.5f - FullWallInstep);
for (var i = 0; i < SharedNavMapSystem.Directions; i++)
{
var dirMask = 1 << i;
if ((tileData & dirMask) == 0)
continue;
var tilePosition = new Vector2(tile.X + 0.5f, -tile.Y - 0.5f);
var angle = -((AtmosDirection) dirMask).ToAngle();
TileRects.Add((angle.RotateVec(leftTop) + tilePosition, angle.RotateVec(rightBottom) + tilePosition));
TileLines.Add((angle.RotateVec(centreTop) + tilePosition, angle.RotateVec(centreBottom) + tilePosition));
}
}
protected void AddOrUpdateNavMapLine(
Vector2i origin,
Vector2i terminus,
Dictionary<Vector2i, Vector2i> lookup,
Dictionary<Vector2i, Vector2i> lookupReversed)
{
Vector2i foundTermius;
Vector2i foundOrigin;
// Does our new line end at the beginning of an existing line?
if (lookup.Remove(terminus, out foundTermius))
{
DebugTools.Assert(lookupReversed[foundTermius] == terminus);
// Does our new line start at the end of an existing line?
if (lookupReversed.Remove(origin, out foundOrigin))
{
// Our new line just connects two existing lines
DebugTools.Assert(lookup[foundOrigin] == origin);
lookup[foundOrigin] = foundTermius;
lookupReversed[foundTermius] = foundOrigin;
}
else
{
// Our new line precedes an existing line, extending it further to the left
lookup[origin] = foundTermius;
lookupReversed[foundTermius] = origin;
}
return;
}
// Does our new line start at the end of an existing line?
if (lookupReversed.Remove(origin, out foundOrigin))
{
// Our new line just extends an existing line further to the right
DebugTools.Assert(lookup[foundOrigin] == origin);
lookup[foundOrigin] = terminus;
lookupReversed[terminus] = foundOrigin;
return;
}
// Completely disconnected line segment.
lookup.Add(origin, terminus);
lookupReversed.Add(terminus, origin);
}
protected Vector2 GetOffset()
@@ -612,15 +732,3 @@ public struct NavMapBlip
Selectable = selectable;
}
}
public struct NavMapLine
{
public readonly Vector2 Origin;
public readonly Vector2 Terminus;
public NavMapLine(Vector2 origin, Vector2 terminus)
{
Origin = origin;
Terminus = terminus;
}
}

View File

@@ -0,0 +1,33 @@
using Content.Shared.Chemistry.Components;
using Content.Shared.Polymorph.Components;
using Content.Shared.Polymorph.Systems;
using Robust.Client.GameObjects;
namespace Content.Client.Polymorph.Systems;
public sealed class ChameleonProjectorSystem : SharedChameleonProjectorSystem
{
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
private EntityQuery<AppearanceComponent> _appearanceQuery;
public override void Initialize()
{
base.Initialize();
_appearanceQuery = GetEntityQuery<AppearanceComponent>();
SubscribeLocalEvent<ChameleonDisguiseComponent, AfterAutoHandleStateEvent>(OnHandleState);
}
private void OnHandleState(Entity<ChameleonDisguiseComponent> ent, ref AfterAutoHandleStateEvent args)
{
CopyComp<SpriteComponent>(ent);
CopyComp<GenericVisualizerComponent>(ent);
CopyComp<SolutionContainerVisualsComponent>(ent);
// reload appearance to hopefully prevent any invisible layers
if (_appearanceQuery.TryComp(ent, out var appearance))
_appearance.QueueUpdate(ent, appearance);
}
}

View File

@@ -5,7 +5,6 @@ using Content.Shared.Popups;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.Player;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface;
using Robust.Shared.Configuration;
using Robust.Shared.Map;
@@ -163,6 +162,15 @@ namespace Content.Client.Popups
PopupEntity(message, uid, type);
}
public override void PopupClient(string? message, EntityUid? recipient, PopupType type = PopupType.Small)
{
if (recipient == null)
return;
if (_timing.IsFirstTimePredicted)
PopupCursor(message, recipient.Value, type);
}
public override void PopupClient(string? message, EntityUid uid, EntityUid? recipient, PopupType type = PopupType.Small)
{
if (recipient == null)
@@ -172,6 +180,15 @@ namespace Content.Client.Popups
PopupEntity(message, uid, recipient.Value, type);
}
public override void PopupClient(string? message, EntityCoordinates coordinates, EntityUid? recipient, PopupType type = PopupType.Small)
{
if (recipient == null)
return;
if (_timing.IsFirstTimePredicted)
PopupCoordinates(message, coordinates, recipient.Value, type);
}
public override void PopupEntity(string? message, EntityUid uid, PopupType type = PopupType.Small)
{
if (TryComp(uid, out TransformComponent? transform))

View File

@@ -0,0 +1,21 @@
using Content.Shared.Power.Components;
using Content.Shared.UserInterface;
using Content.Shared.Wires;
namespace Content.Client.Power;
public sealed class ActivatableUIRequiresPowerSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ActivatableUIRequiresPowerComponent, ActivatableUIOpenAttemptEvent>(OnActivate);
}
private void OnActivate(EntityUid uid, ActivatableUIRequiresPowerComponent component, ActivatableUIOpenAttemptEvent args)
{
// Client can't predict the power properly at the moment so rely upon the server to do it.
args.Cancel();
}
}

View File

@@ -5,6 +5,7 @@ using Robust.Client.Graphics;
using Robust.Shared.Collections;
using Robust.Shared.Map.Components;
using System.Numerics;
using static Content.Shared.Power.SharedPowerMonitoringConsoleSystem;
namespace Content.Client.Power;
@@ -23,8 +24,13 @@ public sealed partial class PowerMonitoringConsoleNavMapControl : NavMapControl
public PowerMonitoringCableNetworksComponent? PowerMonitoringCableNetworks;
public List<PowerMonitoringConsoleLineGroup> HiddenLineGroups = new();
public Dictionary<Vector2i, List<PowerMonitoringConsoleLine>>? PowerCableNetwork;
public Dictionary<Vector2i, List<PowerMonitoringConsoleLine>>? FocusCableNetwork;
public List<PowerMonitoringConsoleLine> PowerCableNetwork = new();
public List<PowerMonitoringConsoleLine> FocusCableNetwork = new();
private Dictionary<Vector2i, Vector2i>[] _horizLines = [new(), new(), new()];
private Dictionary<Vector2i, Vector2i>[] _horizLinesReversed = [new(), new(), new()];
private Dictionary<Vector2i, Vector2i>[] _vertLines = [new(), new(), new()];
private Dictionary<Vector2i, Vector2i>[] _vertLinesReversed = [new(), new(), new()];
private MapGridComponent? _grid;
@@ -48,15 +54,15 @@ public sealed partial class PowerMonitoringConsoleNavMapControl : NavMapControl
if (!_entManager.TryGetComponent<PowerMonitoringCableNetworksComponent>(Owner, out var cableNetworks))
return;
if (!_entManager.TryGetComponent(MapUid, out _grid))
return;
PowerCableNetwork = GetDecodedPowerCableChunks(cableNetworks.AllChunks, _grid);
FocusCableNetwork = GetDecodedPowerCableChunks(cableNetworks.FocusChunks, _grid);
PowerCableNetwork = GetDecodedPowerCableChunks(cableNetworks.AllChunks);
FocusCableNetwork = GetDecodedPowerCableChunks(cableNetworks.FocusChunks);
}
public void DrawAllCableNetworks(DrawingHandleScreen handle)
{
if (!_entManager.TryGetComponent(MapUid, out _grid))
return;
// Draw full cable network
if (PowerCableNetwork != null && PowerCableNetwork.Count > 0)
{
@@ -69,36 +75,29 @@ public sealed partial class PowerMonitoringConsoleNavMapControl : NavMapControl
DrawCableNetwork(handle, FocusCableNetwork, Color.White);
}
public void DrawCableNetwork(DrawingHandleScreen handle, Dictionary<Vector2i, List<PowerMonitoringConsoleLine>> fullCableNetwork, Color modulator)
public void DrawCableNetwork(DrawingHandleScreen handle, List<PowerMonitoringConsoleLine> fullCableNetwork, Color modulator)
{
if (!_entManager.TryGetComponent(MapUid, out _grid))
return;
var offset = GetOffset();
var area = new Box2(-WorldRange, -WorldRange, WorldRange + 1f, WorldRange + 1f).Translated(offset);
offset = offset with { Y = -offset.Y };
if (WorldRange / WorldMaxRange > 0.5f)
{
var cableNetworks = new ValueList<Vector2>[3];
foreach ((var chunk, var chunkedLines) in fullCableNetwork)
foreach (var line in fullCableNetwork)
{
var offsetChunk = new Vector2(chunk.X, chunk.Y) * SharedNavMapSystem.ChunkSize;
if (offsetChunk.X < area.Left - SharedNavMapSystem.ChunkSize || offsetChunk.X > area.Right)
if (HiddenLineGroups.Contains(line.Group))
continue;
if (offsetChunk.Y < area.Bottom - SharedNavMapSystem.ChunkSize || offsetChunk.Y > area.Top)
continue;
var cableOffset = _powerCableOffsets[(int) line.Group];
var start = ScalePosition(line.Origin + cableOffset - offset);
var end = ScalePosition(line.Terminus + cableOffset - offset);
foreach (var chunkedLine in chunkedLines)
{
if (HiddenLineGroups.Contains(chunkedLine.Group))
continue;
var start = ScalePosition(chunkedLine.Origin - new Vector2(offset.X, -offset.Y));
var end = ScalePosition(chunkedLine.Terminus - new Vector2(offset.X, -offset.Y));
cableNetworks[(int) chunkedLine.Group].Add(start);
cableNetworks[(int) chunkedLine.Group].Add(end);
}
cableNetworks[(int) line.Group].Add(start);
cableNetworks[(int) line.Group].Add(end);
}
for (int cableNetworkIdx = 0; cableNetworkIdx < cableNetworks.Length; cableNetworkIdx++)
@@ -124,48 +123,39 @@ public sealed partial class PowerMonitoringConsoleNavMapControl : NavMapControl
{
var cableVertexUVs = new ValueList<Vector2>[3];
foreach ((var chunk, var chunkedLines) in fullCableNetwork)
foreach (var line in fullCableNetwork)
{
var offsetChunk = new Vector2(chunk.X, chunk.Y) * SharedNavMapSystem.ChunkSize;
if (offsetChunk.X < area.Left - SharedNavMapSystem.ChunkSize || offsetChunk.X > area.Right)
if (HiddenLineGroups.Contains(line.Group))
continue;
if (offsetChunk.Y < area.Bottom - SharedNavMapSystem.ChunkSize || offsetChunk.Y > area.Top)
continue;
var cableOffset = _powerCableOffsets[(int) line.Group];
foreach (var chunkedLine in chunkedLines)
{
if (HiddenLineGroups.Contains(chunkedLine.Group))
continue;
var leftTop = ScalePosition(new Vector2
(Math.Min(line.Origin.X, line.Terminus.X) - 0.1f,
Math.Min(line.Origin.Y, line.Terminus.Y) - 0.1f)
+ cableOffset - offset);
var leftTop = ScalePosition(new Vector2
(Math.Min(chunkedLine.Origin.X, chunkedLine.Terminus.X) - 0.1f,
Math.Min(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) - 0.1f)
- new Vector2(offset.X, -offset.Y));
var rightTop = ScalePosition(new Vector2
(Math.Max(line.Origin.X, line.Terminus.X) + 0.1f,
Math.Min(line.Origin.Y, line.Terminus.Y) - 0.1f)
+ cableOffset - offset);
var rightTop = ScalePosition(new Vector2
(Math.Max(chunkedLine.Origin.X, chunkedLine.Terminus.X) + 0.1f,
Math.Min(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) - 0.1f)
- new Vector2(offset.X, -offset.Y));
var leftBottom = ScalePosition(new Vector2
(Math.Min(line.Origin.X, line.Terminus.X) - 0.1f,
Math.Max(line.Origin.Y, line.Terminus.Y) + 0.1f)
+ cableOffset - offset);
var leftBottom = ScalePosition(new Vector2
(Math.Min(chunkedLine.Origin.X, chunkedLine.Terminus.X) - 0.1f,
Math.Max(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) + 0.1f)
- new Vector2(offset.X, -offset.Y));
var rightBottom = ScalePosition(new Vector2
(Math.Max(line.Origin.X, line.Terminus.X) + 0.1f,
Math.Max(line.Origin.Y, line.Terminus.Y) + 0.1f)
+ cableOffset - offset);
var rightBottom = ScalePosition(new Vector2
(Math.Max(chunkedLine.Origin.X, chunkedLine.Terminus.X) + 0.1f,
Math.Max(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) + 0.1f)
- new Vector2(offset.X, -offset.Y));
cableVertexUVs[(int) chunkedLine.Group].Add(leftBottom);
cableVertexUVs[(int) chunkedLine.Group].Add(leftTop);
cableVertexUVs[(int) chunkedLine.Group].Add(rightBottom);
cableVertexUVs[(int) chunkedLine.Group].Add(leftTop);
cableVertexUVs[(int) chunkedLine.Group].Add(rightBottom);
cableVertexUVs[(int) chunkedLine.Group].Add(rightTop);
}
cableVertexUVs[(int) line.Group].Add(leftBottom);
cableVertexUVs[(int) line.Group].Add(leftTop);
cableVertexUVs[(int) line.Group].Add(rightBottom);
cableVertexUVs[(int) line.Group].Add(leftTop);
cableVertexUVs[(int) line.Group].Add(rightBottom);
cableVertexUVs[(int) line.Group].Add(rightTop);
}
for (int cableNetworkIdx = 0; cableNetworkIdx < cableVertexUVs.Length; cableNetworkIdx++)
@@ -188,34 +178,43 @@ public sealed partial class PowerMonitoringConsoleNavMapControl : NavMapControl
}
}
public Dictionary<Vector2i, List<PowerMonitoringConsoleLine>>? GetDecodedPowerCableChunks(Dictionary<Vector2i, PowerCableChunk>? chunks, MapGridComponent? grid)
public List<PowerMonitoringConsoleLine> GetDecodedPowerCableChunks(Dictionary<Vector2i, PowerCableChunk>? chunks)
{
if (chunks == null || grid == null)
return null;
var decodedOutput = new List<PowerMonitoringConsoleLine>();
var decodedOutput = new Dictionary<Vector2i, List<PowerMonitoringConsoleLine>>();
if (!_entManager.TryGetComponent(MapUid, out _grid))
return decodedOutput;
foreach ((var chunkOrigin, var chunk) in chunks)
if (chunks == null)
return decodedOutput;
Array.ForEach(_horizLines, x=> x.Clear());
Array.ForEach(_horizLinesReversed, x=> x.Clear());
Array.ForEach(_vertLines, x=> x.Clear());
Array.ForEach(_vertLinesReversed, x=> x.Clear());
foreach (var (chunkOrigin, chunk) in chunks)
{
var list = new List<PowerMonitoringConsoleLine>();
for (int cableIdx = 0; cableIdx < chunk.PowerCableData.Length; cableIdx++)
for (var cableIdx = 0; cableIdx < 3; cableIdx++)
{
var horizLines = _horizLines[cableIdx];
var horizLinesReversed = _horizLinesReversed[cableIdx];
var vertLines = _vertLines[cableIdx];
var vertLinesReversed = _vertLinesReversed[cableIdx];
var chunkMask = chunk.PowerCableData[cableIdx];
Vector2 offset = _powerCableOffsets[cableIdx];
for (var chunkIdx = 0; chunkIdx < SharedNavMapSystem.ChunkSize * SharedNavMapSystem.ChunkSize; chunkIdx++)
for (var chunkIdx = 0; chunkIdx < ChunkSize * ChunkSize; chunkIdx++)
{
var value = (int) Math.Pow(2, chunkIdx);
var value = 1 << chunkIdx;
var mask = chunkMask & value;
if (mask == 0x0)
continue;
var relativeTile = SharedNavMapSystem.GetTile(mask);
var tile = (chunk.Origin * SharedNavMapSystem.ChunkSize + relativeTile) * grid.TileSize;
var position = new Vector2(tile.X, -tile.Y);
var relativeTile = GetTileFromIndex(chunkIdx);
var tile = (chunk.Origin * ChunkSize + relativeTile) * _grid.TileSize;
tile = tile with { Y = -tile.Y };
PowerCableChunk neighborChunk;
bool neighbor;
@@ -223,56 +222,65 @@ public sealed partial class PowerMonitoringConsoleNavMapControl : NavMapControl
// Note: we only check the north and east neighbors
// East
if (relativeTile.X == SharedNavMapSystem.ChunkSize - 1)
if (relativeTile.X == ChunkSize - 1)
{
neighbor = chunks.TryGetValue(chunkOrigin + new Vector2i(1, 0), out neighborChunk) &&
(neighborChunk.PowerCableData[cableIdx] & SharedNavMapSystem.GetFlag(new Vector2i(0, relativeTile.Y))) != 0x0;
(neighborChunk.PowerCableData[cableIdx] & GetFlag(new Vector2i(0, relativeTile.Y))) != 0x0;
}
else
{
var flag = SharedNavMapSystem.GetFlag(relativeTile + new Vector2i(1, 0));
var flag = GetFlag(relativeTile + new Vector2i(1, 0));
neighbor = (chunkMask & flag) != 0x0;
}
if (neighbor)
{
// Add points
var line = new PowerMonitoringConsoleLine
(position + offset + new Vector2(grid.TileSize * 0.5f, -grid.TileSize * 0.5f),
position + new Vector2(1f, 0f) + offset + new Vector2(grid.TileSize * 0.5f, -grid.TileSize * 0.5f),
(PowerMonitoringConsoleLineGroup) cableIdx);
list.Add(line);
AddOrUpdateNavMapLine(tile, tile + new Vector2i(_grid.TileSize, 0), horizLines, horizLinesReversed);
}
// North
if (relativeTile.Y == SharedNavMapSystem.ChunkSize - 1)
if (relativeTile.Y == ChunkSize - 1)
{
neighbor = chunks.TryGetValue(chunkOrigin + new Vector2i(0, 1), out neighborChunk) &&
(neighborChunk.PowerCableData[cableIdx] & SharedNavMapSystem.GetFlag(new Vector2i(relativeTile.X, 0))) != 0x0;
(neighborChunk.PowerCableData[cableIdx] & GetFlag(new Vector2i(relativeTile.X, 0))) != 0x0;
}
else
{
var flag = SharedNavMapSystem.GetFlag(relativeTile + new Vector2i(0, 1));
var flag = GetFlag(relativeTile + new Vector2i(0, 1));
neighbor = (chunkMask & flag) != 0x0;
}
if (neighbor)
{
// Add points
var line = new PowerMonitoringConsoleLine
(position + offset + new Vector2(grid.TileSize * 0.5f, -grid.TileSize * 0.5f),
position + new Vector2(0f, -1f) + offset + new Vector2(grid.TileSize * 0.5f, -grid.TileSize * 0.5f),
(PowerMonitoringConsoleLineGroup) cableIdx);
list.Add(line);
AddOrUpdateNavMapLine(tile + new Vector2i(0, -_grid.TileSize), tile, vertLines, vertLinesReversed);
}
}
}
}
if (list.Count > 0)
decodedOutput.Add(chunkOrigin, list);
var gridOffset = new Vector2(_grid.TileSize * 0.5f, -_grid.TileSize * 0.5f);
for (var index = 0; index < _horizLines.Length; index++)
{
var horizLines = _horizLines[index];
foreach (var (origin, terminal) in horizLines)
{
decodedOutput.Add(new PowerMonitoringConsoleLine(origin + gridOffset, terminal + gridOffset,
(PowerMonitoringConsoleLineGroup) index));
}
}
for (var index = 0; index < _vertLines.Length; index++)
{
var vertLines = _vertLines[index];
foreach (var (origin, terminal) in vertLines)
{
decodedOutput.Add(new PowerMonitoringConsoleLine(origin + gridOffset, terminal + gridOffset,
(PowerMonitoringConsoleLineGroup) index));
}
}
return decodedOutput;

View File

@@ -170,9 +170,6 @@ public sealed partial class PowerMonitoringWindow : FancyWindow
NavMap.TrackedEntities[mon.Value] = blip;
}
// Update nav map
NavMap.ForceNavMapUpdate();
// If the entry group doesn't match the current tab, the data is out dated, do not use it
if (allEntries.Length > 0 && allEntries[0].Group != GetCurrentPowerMonitoringConsoleGroup())
return;

View File

@@ -135,6 +135,9 @@ namespace Content.Client.Preferences.UI
_humanoidProfileEditor.CharacterSlot = characterIndexCopy;
_humanoidProfileEditor.UpdateControls();
_preferencesManager.SelectCharacter(character);
var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
controller.UpdateProfile(_humanoidProfileEditor.Profile);
controller.ReloadCharacterUI();
UpdateUI();
args.Event.Handle();
};

View File

@@ -697,6 +697,20 @@ namespace Content.Client.Preferences.UI
var color = SkinColor.TintedHues(_rgbSkinColorSelector.Color);
CMarkings.CurrentSkinColor = color;
Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithSkinColor(color));
break;
}
case HumanoidSkinColor.VoxFeathers:
{
if (!_rgbSkinColorContainer.Visible)
{
_skinColor.Visible = false;
_rgbSkinColorContainer.Visible = true;
}
var color = SkinColor.ClosestVoxColor(_rgbSkinColorSelector.Color);
CMarkings.CurrentSkinColor = color;
Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithSkinColor(color));
break;
@@ -728,7 +742,6 @@ namespace Content.Client.Preferences.UI
CharacterSlot = _preferencesManager.Preferences.SelectedCharacterIndex;
UpdateAntagRequirements();
UpdateRoleRequirements();
UpdateControls();
ShowClothes.Pressed = true;
}
@@ -908,6 +921,18 @@ namespace Content.Client.Preferences.UI
_rgbSkinColorSelector.Color = Profile.Appearance.SkinColor;
break;
}
case HumanoidSkinColor.VoxFeathers:
{
if (!_rgbSkinColorContainer.Visible)
{
_skinColor.Visible = false;
_rgbSkinColorContainer.Visible = true;
}
_rgbSkinColorSelector.Color = SkinColor.ClosestVoxColor(Profile.Appearance.SkinColor);
break;
}
}
}
@@ -1115,6 +1140,7 @@ namespace Content.Client.Preferences.UI
UpdateEyePickers();
UpdateSaveButton();
UpdateLoadouts();
UpdateRoleRequirements();
UpdateJobPriorities();
UpdateAntagPreferences();
UpdateTraitPreferences();

View File

@@ -195,9 +195,16 @@ public sealed partial class ReplaySpectatorSystem
if (uid != _player.LocalEntity)
return;
if (args.Transform.MapUid != null || args.OldMapId == MapId.Nullspace)
if (args.Transform.MapUid != null || args.OldMapId == null)
return;
if (_spectatorData != null)
{
// Currently scrubbing/setting the replay tick
// the observer will get respawned once the state was applied
return;
}
// The entity being spectated from was moved to null-space.
// This was probably because they were spectating some entity in a client-side replay that left PVS range.
// Simple respawn the ghost.

View File

@@ -0,0 +1,51 @@
using Content.Client.GameTicking.Managers;
using Content.Shared.GameTicking;
using Content.Shared.Input;
using JetBrains.Annotations;
using Robust.Client.Input;
using Robust.Client.UserInterface.Controllers;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;
namespace Content.Client.RoundEnd;
[UsedImplicitly]
public sealed class RoundEndSummaryUIController : UIController,
IOnSystemLoaded<ClientGameTicker>
{
[Dependency] private readonly IInputManager _input = default!;
private RoundEndSummaryWindow? _window;
private void ToggleScoreboardWindow(ICommonSession? session = null)
{
if (_window == null)
return;
if (_window.IsOpen)
{
_window.Close();
}
else
{
_window.OpenCenteredRight();
_window.MoveToFront();
}
}
public void OpenRoundEndSummaryWindow(RoundEndMessageEvent message)
{
// Don't open duplicate windows (mainly for replays).
if (_window?.RoundId == message.RoundId)
return;
_window = new RoundEndSummaryWindow(message.GamemodeTitle, message.RoundEndText,
message.RoundDuration, message.RoundId, message.AllPlayersEndInfo, EntityManager);
}
public void OnSystemLoaded(ClientGameTicker system)
{
_input.SetInputCommand(ContentKeyFunctions.ToggleRoundEndSummaryWindow,
InputCmdHandler.FromDelegate(ToggleScoreboardWindow));
}
}

View File

@@ -2,7 +2,6 @@ using System.Linq;
using System.Numerics;
using Content.Client.Message;
using Content.Shared.GameTicking;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Utility;

View File

@@ -100,7 +100,7 @@ public partial class BaseShuttleControl : MapGridControl
var textDimensions = handle.GetDimensions(Font, text, UIScale);
handle.DrawCircle(origin, scaledRadius, color, false);
handle.DrawString(Font, ScalePosition(new Vector2(0f, -radius)) - new Vector2(0f, textDimensions.Y), text, color);
handle.DrawString(Font, ScalePosition(new Vector2(0f, -radius)) - new Vector2(0f, textDimensions.Y), text, UIScale, color);
}
const int gridLinesRadial = 8;

View File

@@ -2,7 +2,4 @@ using Content.Shared.Station;
namespace Content.Client.Station;
public sealed class StationSpawningSystem : SharedStationSpawningSystem
{
}
public sealed class StationSpawningSystem : SharedStationSpawningSystem;

View File

@@ -17,6 +17,14 @@ public sealed class StorageBoundUserInterface : BoundUserInterface
_storage = _entManager.System<StorageSystem>();
}
protected override void Open()
{
base.Open();
if (_entManager.TryGetComponent<StorageComponent>(Owner, out var comp))
_storage.OpenStorageWindow((Owner, comp));
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
@@ -25,16 +33,5 @@ public sealed class StorageBoundUserInterface : BoundUserInterface
_storage.CloseStorageWindow(Owner);
}
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
base.ReceiveMessage(message);
if (message is StorageModifyWindowMessage)
{
if (_entManager.TryGetComponent<StorageComponent>(Owner, out var comp))
_storage.OpenStorageWindow((Owner, comp));
}
}
}

View File

@@ -26,7 +26,7 @@ public sealed class StorageSystem : SharedStorageSystem
SubscribeLocalEvent<StorageComponent, ComponentShutdown>(OnShutdown);
SubscribeNetworkEvent<PickupAnimationEvent>(HandlePickupAnimation);
SubscribeNetworkEvent<AnimateInsertingEntitiesEvent>(HandleAnimatingInsertingEntities);
SubscribeAllEvent<AnimateInsertingEntitiesEvent>(HandleAnimatingInsertingEntities);
}
public override void UpdateUI(Entity<StorageComponent?> entity)
@@ -111,7 +111,7 @@ public sealed class StorageSystem : SharedStorageSystem
if (!Resolve(entity, ref entity.Comp, false))
return;
if (entity.Comp.OpenInterfaces.GetValueOrDefault(StorageComponent.StorageUiKey.Key) is not { } bui)
if (entity.Comp.ClientOpenInterfaces.GetValueOrDefault(StorageComponent.StorageUiKey.Key) is not { } bui)
return;
bui.Close();

View File

@@ -35,7 +35,7 @@ public sealed class StrippableSystem : SharedStrippableSystem
if (!TryComp(uid, out UserInterfaceComponent? uiComp))
return;
foreach (var ui in uiComp.OpenInterfaces.Values)
foreach (var ui in uiComp.ClientOpenInterfaces.Values)
{
if (ui is StrippableBoundUserInterface stripUi)
stripUi.DirtyMenu();

View File

@@ -136,6 +136,8 @@ namespace Content.Client.Stylesheets
public const string StyleClassPowerStateGood = "PowerStateGood";
public const string StyleClassItemStatus = "ItemStatus";
public const string StyleClassItemStatusNotHeld = "ItemStatusNotHeld";
public static readonly Color ItemStatusNotHeldColor = Color.Gray;
//Background
public const string StyleClassBackgroundBaseDark = "PanelBackgroundBaseDark";
@@ -1234,6 +1236,16 @@ namespace Content.Client.Stylesheets
new StyleProperty("font", notoSans10),
}),
Element()
.Class(StyleClassItemStatusNotHeld)
.Prop("font", notoSansItalic10)
.Prop("font-color", ItemStatusNotHeldColor),
Element<RichTextLabel>()
.Class(StyleClassItemStatus)
.Prop(nameof(RichTextLabel.LineHeightScale), 0.7f)
.Prop(nameof(Control.Margin), new Thickness(0, 0, 0, -6)),
// Slider
new StyleRule(SelectorElement.Type(typeof(Slider)), new []
{

View File

@@ -0,0 +1,11 @@
<tips:TippyUI xmlns="https://spacestation14.io"
xmlns:tips="clr-namespace:Content.Client.Tips"
MinSize="64 64"
Visible="False">
<PanelContainer Name="LabelPanel" Access="Public" Visible="False" MaxWidth="300" MaxHeight="200">
<ScrollContainer Name="ScrollingContents" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalExpand="True" VerticalExpand="True" HScrollEnabled="False" ReturnMeasure="True">
<RichTextLabel Name="Label" Access="Public"/>
</ScrollContainer>
</PanelContainer>
<SpriteView Name="Entity" Access="Public" MinSize="128 128"/>
</tips:TippyUI>

View File

@@ -0,0 +1,54 @@
using Content.Client.Paper;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client.Tips;
[GenerateTypedNameReferences]
public sealed partial class TippyUI : UIWidget
{
public TippyState State = TippyState.Hidden;
public bool ModifyLayers = true;
public TippyUI()
{
RobustXamlLoader.Load(this);
}
public void InitLabel(PaperVisualsComponent? visuals, IResourceCache resCache)
{
if (visuals == null)
return;
Label.ModulateSelfOverride = visuals.FontAccentColor;
if (visuals.BackgroundImagePath == null)
return;
LabelPanel.ModulateSelfOverride = visuals.BackgroundModulate;
var backgroundImage = resCache.GetResource<TextureResource>(visuals.BackgroundImagePath);
var backgroundImageMode = visuals.BackgroundImageTile ? StyleBoxTexture.StretchMode.Tile : StyleBoxTexture.StretchMode.Stretch;
var backgroundPatchMargin = visuals.BackgroundPatchMargin;
LabelPanel.PanelOverride = new StyleBoxTexture
{
Texture = backgroundImage,
TextureScale = visuals.BackgroundScale,
Mode = backgroundImageMode,
PatchMarginLeft = backgroundPatchMargin.Left,
PatchMarginBottom = backgroundPatchMargin.Bottom,
PatchMarginRight = backgroundPatchMargin.Right,
PatchMarginTop = backgroundPatchMargin.Top
};
}
public enum TippyState : byte
{
Hidden,
Revealing,
Speaking,
Hiding,
}
}

View File

@@ -0,0 +1,241 @@
using Content.Client.Gameplay;
using System.Numerics;
using Content.Client.Message;
using Content.Client.Paper;
using Content.Shared.CCVar;
using Content.Shared.Movement.Components;
using Content.Shared.Tips;
using Robust.Client.GameObjects;
using Robust.Client.ResourceManagement;
using Robust.Client.State;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controls;
using Robust.Client.Audio;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using static Content.Client.Tips.TippyUI;
namespace Content.Client.Tips;
public sealed class TippyUIController : UIController
{
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IResourceCache _resCache = default!;
[UISystemDependency] private readonly AudioSystem _audio = default!;
public const float Padding = 50;
public static Angle WaddleRotation = Angle.FromDegrees(10);
private EntityUid _entity;
private float _secondsUntilNextState;
private int _previousStep = 0;
private TippyEvent? _currentMessage;
private readonly Queue<TippyEvent> _queuedMessages = new();
public override void Initialize()
{
base.Initialize();
UIManager.OnScreenChanged += OnScreenChanged;
SubscribeNetworkEvent<TippyEvent>(OnTippyEvent);
}
private void OnTippyEvent(TippyEvent msg, EntitySessionEventArgs args)
{
_queuedMessages.Enqueue(msg);
}
public override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
var screen = UIManager.ActiveScreen;
if (screen == null)
{
_queuedMessages.Clear();
return;
}
var tippy = screen.GetOrAddWidget<TippyUI>();
_secondsUntilNextState -= args.DeltaSeconds;
if (_secondsUntilNextState <= 0)
NextState(tippy);
else
{
var pos = UpdatePosition(tippy, screen.Size, args); ;
LayoutContainer.SetPosition(tippy, pos);
}
}
private Vector2 UpdatePosition(TippyUI tippy, Vector2 screenSize, FrameEventArgs args)
{
if (_currentMessage == null)
return default;
var slideTime = _currentMessage.SlideTime;
var offset = tippy.State switch
{
TippyState.Hidden => 0,
TippyState.Revealing => Math.Clamp(1 - _secondsUntilNextState / slideTime, 0, 1),
TippyState.Hiding => Math.Clamp(_secondsUntilNextState / slideTime, 0, 1),
_ => 1,
};
var waddle = _currentMessage.WaddleInterval;
if (_currentMessage == null
|| waddle <= 0
|| tippy.State == TippyState.Hidden
|| tippy.State == TippyState.Speaking
|| !EntityManager.TryGetComponent(_entity, out SpriteComponent? sprite))
{
return new Vector2(screenSize.X - offset * (tippy.DesiredSize.X + Padding), (screenSize.Y - tippy.DesiredSize.Y) / 2);
}
var numSteps = (int) Math.Ceiling(slideTime / waddle);
var curStep = (int) Math.Floor(numSteps * offset);
var stepSize = (tippy.DesiredSize.X + Padding) / numSteps;
if (curStep != _previousStep)
{
_previousStep = curStep;
sprite.Rotation = sprite.Rotation > 0
? -WaddleRotation
: WaddleRotation;
if (EntityManager.TryGetComponent(_entity, out FootstepModifierComponent? step))
{
var audioParams = step.FootstepSoundCollection.Params
.AddVolume(-7f)
.WithVariation(0.1f);
_audio.PlayGlobal(step.FootstepSoundCollection, EntityUid.Invalid, audioParams);
}
}
return new Vector2(screenSize.X - stepSize * curStep, (screenSize.Y - tippy.DesiredSize.Y) / 2);
}
private void NextState(TippyUI tippy)
{
SpriteComponent? sprite;
switch (tippy.State)
{
case TippyState.Hidden:
if (!_queuedMessages.TryDequeue(out var next))
return;
if (next.Proto != null)
{
_entity = EntityManager.SpawnEntity(next.Proto, MapCoordinates.Nullspace);
tippy.ModifyLayers = false;
}
else
{
_entity = EntityManager.SpawnEntity(_cfg.GetCVar(CCVars.TippyEntity), MapCoordinates.Nullspace);
tippy.ModifyLayers = true;
}
if (!EntityManager.TryGetComponent(_entity, out sprite))
return;
if (!EntityManager.HasComponent<PaperVisualsComponent>(_entity))
{
var paper = EntityManager.AddComponent<PaperVisualsComponent>(_entity);
paper.BackgroundImagePath = "/Textures/Interface/Paper/paper_background_default.svg.96dpi.png";
paper.BackgroundPatchMargin = new(16f, 16f, 16f, 16f);
paper.BackgroundModulate = new(255, 255, 204);
paper.FontAccentColor = new(0, 0, 0);
}
tippy.InitLabel(EntityManager.GetComponentOrNull<PaperVisualsComponent>(_entity), _resCache);
var scale = sprite.Scale;
if (tippy.ModifyLayers)
{
sprite.Scale = Vector2.One;
}
else
{
sprite.Scale = new Vector2(3, 3);
}
tippy.Entity.SetEntity(_entity);
tippy.Entity.Scale = scale;
_currentMessage = next;
_secondsUntilNextState = next.SlideTime;
tippy.State = TippyState.Revealing;
_previousStep = 0;
if (tippy.ModifyLayers)
{
sprite.LayerSetAnimationTime("revealing", 0);
sprite.LayerSetVisible("revealing", true);
sprite.LayerSetVisible("speaking", false);
sprite.LayerSetVisible("hiding", false);
}
sprite.Rotation = 0;
tippy.Label.SetMarkup(_currentMessage.Msg);
tippy.Label.Visible = false;
tippy.LabelPanel.Visible = false;
tippy.Visible = true;
sprite.Visible = true;
break;
case TippyState.Revealing:
tippy.State = TippyState.Speaking;
if (!EntityManager.TryGetComponent(_entity, out sprite))
return;
sprite.Rotation = 0;
_previousStep = 0;
if (tippy.ModifyLayers)
{
sprite.LayerSetAnimationTime("speaking", 0);
sprite.LayerSetVisible("revealing", false);
sprite.LayerSetVisible("speaking", true);
sprite.LayerSetVisible("hiding", false);
}
tippy.Label.Visible = true;
tippy.LabelPanel.Visible = true;
tippy.InvalidateArrange();
tippy.InvalidateMeasure();
if (_currentMessage != null)
_secondsUntilNextState = _currentMessage.SpeakTime;
break;
case TippyState.Speaking:
tippy.State = TippyState.Hiding;
if (!EntityManager.TryGetComponent(_entity, out sprite))
return;
if (tippy.ModifyLayers)
{
sprite.LayerSetAnimationTime("hiding", 0);
sprite.LayerSetVisible("revealing", false);
sprite.LayerSetVisible("speaking", false);
sprite.LayerSetVisible("hiding", true);
}
tippy.LabelPanel.Visible = false;
if (_currentMessage != null)
_secondsUntilNextState = _currentMessage.SlideTime;
break;
default: // finished hiding
EntityManager.DeleteEntity(_entity);
_entity = default;
tippy.Visible = false;
_currentMessage = null;
_secondsUntilNextState = 0;
tippy.State = TippyState.Hidden;
break;
}
}
private void OnScreenChanged((UIScreen? Old, UIScreen? New) ev)
{
ev.Old?.RemoveWidget<TippyUI>();
_currentMessage = null;
EntityManager.DeleteEntity(_entity);
}
}

View File

@@ -1,18 +0,0 @@
using Content.Client.Tools.UI;
using Content.Shared.Tools.Components;
namespace Content.Client.Tools.Components
{
[RegisterComponent, Access(typeof(ToolSystem), typeof(WelderStatusControl))]
public sealed partial class WelderComponent : SharedWelderComponent
{
[ViewVariables(VVAccess.ReadWrite)]
public bool UiUpdateNeeded { get; set; }
[ViewVariables]
public float FuelCapacity { get; set; }
[ViewVariables]
public float Fuel { get; set; }
}
}

View File

@@ -1,10 +1,8 @@
using Content.Client.Items;
using Content.Client.Tools.Components;
using Content.Client.Tools.UI;
using Content.Shared.Item;
using Content.Shared.Tools.Components;
using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem;
namespace Content.Client.Tools
@@ -15,8 +13,7 @@ namespace Content.Client.Tools
{
base.Initialize();
SubscribeLocalEvent<WelderComponent, ComponentHandleState>(OnWelderHandleState);
Subs.ItemStatus<WelderComponent>(ent => new WelderStatusControl(ent));
Subs.ItemStatus<WelderComponent>(ent => new WelderStatusControl(ent, EntityManager, this));
Subs.ItemStatus<MultipleToolComponent>(ent => new MultipleToolStatusControl(ent));
}
@@ -42,20 +39,5 @@ namespace Content.Client.Tools
sprite.LayerSetSprite(0, current.Sprite);
}
}
private void OnWelderHandleState(EntityUid uid, WelderComponent welder, ref ComponentHandleState args)
{
if (args.Current is not WelderComponentState state)
return;
welder.FuelCapacity = state.FuelCapacity;
welder.Fuel = state.Fuel;
welder.UiUpdateNeeded = true;
}
protected override bool IsWelder(EntityUid uid)
{
return HasComp<WelderComponent>(uid);
}
}
}

View File

@@ -1,62 +1,45 @@
using Content.Client.Items.UI;
using Content.Client.Message;
using Content.Client.Stylesheets;
using Content.Client.Tools.Components;
using Content.Shared.Item;
using Robust.Client.UserInterface;
using Content.Shared.FixedPoint;
using Content.Shared.Tools.Components;
using Content.Shared.Tools.Systems;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Timing;
using ItemToggleComponent = Content.Shared.Item.ItemToggle.Components.ItemToggleComponent;
namespace Content.Client.Tools.UI;
public sealed class WelderStatusControl : Control
public sealed class WelderStatusControl : PollingItemStatusControl<WelderStatusControl.Data>
{
[Dependency] private readonly IEntityManager _entMan = default!;
private readonly WelderComponent _parent;
private readonly ItemToggleComponent? _toggleComponent;
private readonly Entity<WelderComponent> _parent;
private readonly IEntityManager _entityManager;
private readonly SharedToolSystem _toolSystem;
private readonly RichTextLabel _label;
public WelderStatusControl(Entity<WelderComponent> parent)
public WelderStatusControl(Entity<WelderComponent> parent, IEntityManager entityManager, SharedToolSystem toolSystem)
{
_parent = parent;
_entMan = IoCManager.Resolve<IEntityManager>();
if (_entMan.TryGetComponent<ItemToggleComponent>(parent, out var itemToggle))
_toggleComponent = itemToggle;
_entityManager = entityManager;
_toolSystem = toolSystem;
_label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
AddChild(_label);
UpdateDraw();
}
/// <inheritdoc />
protected override void FrameUpdate(FrameEventArgs args)
protected override Data PollData()
{
base.FrameUpdate(args);
if (!_parent.UiUpdateNeeded)
{
return;
}
Update();
var (fuel, capacity) = _toolSystem.GetWelderFuelAndCapacity(_parent, _parent.Comp);
return new Data(fuel, capacity, _parent.Comp.Enabled);
}
public void Update()
protected override void Update(in Data data)
{
_parent.UiUpdateNeeded = false;
var fuelCap = _parent.FuelCapacity;
var fuel = _parent.Fuel;
var lit = false;
if (_toggleComponent != null)
{
lit = _toggleComponent.Activated;
}
_label.SetMarkup(Loc.GetString("welder-component-on-examine-detailed-message",
("colorName", fuel < fuelCap / 4f ? "darkorange" : "orange"),
("fuelLeft", Math.Round(fuel, 1)),
("fuelCapacity", fuelCap),
("status", Loc.GetString(lit ? "welder-component-on-examine-welder-lit-message" : "welder-component-on-examine-welder-not-lit-message"))));
("colorName", data.Fuel < data.FuelCapacity / 4f ? "darkorange" : "orange"),
("fuelLeft", data.Fuel),
("fuelCapacity", data.FuelCapacity),
("status", Loc.GetString(data.Lit ? "welder-component-on-examine-welder-lit-message" : "welder-component-on-examine-welder-not-lit-message"))));
}
public record struct Data(FixedPoint2 Fuel, FixedPoint2 FuelCapacity, bool Lit);
}

View File

@@ -0,0 +1,55 @@
using System.Numerics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
namespace Content.Client.UserInterface.Controls;
/// <summary>
/// Pretends to child controls that there's infinite space.
/// This can be used to make something like a <see cref="RichTextLabel"/> clip instead of wrapping.
/// </summary>
public sealed class ClipControl : Control
{
private bool _clipHorizontal = true;
private bool _clipVertical = true;
public bool ClipHorizontal
{
get => _clipHorizontal;
set
{
_clipHorizontal = value;
InvalidateMeasure();
}
}
public bool ClipVertical
{
get => _clipVertical;
set
{
_clipVertical = value;
InvalidateMeasure();
}
}
protected override Vector2 MeasureOverride(Vector2 availableSize)
{
if (ClipHorizontal)
availableSize = availableSize with { X = float.PositiveInfinity };
if (ClipVertical)
availableSize = availableSize with { Y = float.PositiveInfinity };
return base.MeasureOverride(availableSize);
}
protected override Vector2 ArrangeOverride(Vector2 finalSize)
{
foreach (var child in Children)
{
child.Arrange(UIBox2.FromDimensions(Vector2.Zero, child.DesiredSize));
}
return finalSize;
}
}

View File

@@ -51,6 +51,7 @@ namespace Content.Client.UserInterface.Controls
var stretch = _cfg.GetCVar(CCVars.ViewportStretch);
var renderScaleUp = _cfg.GetCVar(CCVars.ViewportScaleRender);
var fixedFactor = _cfg.GetCVar(CCVars.ViewportFixedScaleFactor);
var verticalFit = _cfg.GetCVar(CCVars.ViewportVerticalFit);
if (stretch)
{
@@ -60,6 +61,7 @@ namespace Content.Client.UserInterface.Controls
// Did not find a snap, enable stretching.
Viewport.FixedStretchSize = null;
Viewport.StretchMode = ScalingViewportStretchMode.Bilinear;
Viewport.IgnoreDimension = verticalFit ? ScalingViewportIgnoreDimension.Horizontal : ScalingViewportIgnoreDimension.None;
if (renderScaleUp)
{
@@ -104,6 +106,8 @@ namespace Content.Client.UserInterface.Controls
// where we are clipping the viewport to make it fit.
var cfgToleranceClip = _cfg.GetCVar(CCVars.ViewportSnapToleranceClip);
var cfgVerticalFit = _cfg.GetCVar(CCVars.ViewportVerticalFit);
// Calculate if the viewport, when rendered at an integer scale,
// is close enough to the control size to enable "snapping" to NN,
// potentially cutting a tiny bit off/leaving a margin.
@@ -123,7 +127,8 @@ namespace Content.Client.UserInterface.Controls
// The rule for which snap fits is that at LEAST one axis needs to be in the tolerance size wise.
// One axis MAY be larger but not smaller than tolerance.
// Obviously if it's too small it's bad, and if it's too big on both axis we should stretch up.
if (Fits(dx) && Fits(dy) || Fits(dx) && Larger(dy) || Larger(dx) && Fits(dy))
// Additionally, if the viewport's supposed to be vertically fit, then the horizontal scale should just be ignored where appropriate.
if ((Fits(dx) || cfgVerticalFit) && Fits(dy) || !cfgVerticalFit && Fits(dx) && Larger(dy) || Larger(dx) && Fits(dy))
{
// Found snap that fits.
return i;

Some files were not shown because too many files have changed in this diff Show More