Compare commits

...

278 Commits

Author SHA1 Message Date
Ed
fd3f222e7d Update CP14BiomeSpawnerSystem.cs 2024-07-30 13:21:06 +03:00
Ed
1f587c10b8 Update LICENSE.TXT 2024-07-30 11:48:50 +03:00
Ed
22bb0ae283 Energy pilons WIP (#326)
* split partial magic system

* add debug sprited pilons

* some energy pilons interactions

* Update CP14MagicEnergySystem.Relay.cs

* spupers (#322)

* spupers

* meta

* aura nodes + aura scanners

* scanner sprites

* maid dress

* reverse pilon logic

* relay delete, code clean up

* delete content

* Update basic.yml

* Update shirt.yml

* Update crystal.yml

---------

Co-authored-by: Jaraten <116667537+Jaraten@users.noreply.github.com>
2024-07-29 21:01:36 +03:00
Gagarinten-Noverdo
c69cb0320e Biome spawner update. Round seed system (#359)
* Biome spawner update. Round seed system

* Format fix

* Round seed M I T

* Error to Warning

* Test fix #2

* Test fix #3

* VV

* Del out of body
2024-07-29 19:16:55 +03:00
Ed
02c5e03ae7 Merge pull request #362 from crystallpunk-14/ed-28-07-2024-upstream
Upstream sync
2024-07-28 22:22:55 +03:00
Ed
cc5f27c057 ignore traits 2024-07-28 21:04:45 +03:00
Ed
fb40f8cd25 Merge remote-tracking branch 'upstream/master' into ed-28-07-2024-upstream
# Conflicts:
#	Resources/Prototypes/Maps/core.yml
#	Resources/Prototypes/Maps/train.yml
#	Resources/Prototypes/Traits/categories.yml
#	Resources/Prototypes/Traits/disabilities.yml
2024-07-28 20:58:48 +03:00
Ed
0d345c33b9 Update dev_map.yml (#361)
* Update dev_map.yml

* Disable FTL test

* DisableEvacTest
2024-07-28 20:56:05 +03:00
Ed
9011aab26b Add 3 roles (without gameplay, alas) (#356)
* add role icons

* add roles prototype

* Update job.yml
2024-07-28 18:22:50 +03:00
Jaraten
cf6b42d20c Stone-brick wall crushed (#336) 2024-07-28 17:27:24 +03:00
Ed
655b32b720 Magic spells backend (#358)
* add EntityEffect aability support

* delayed actions

* renaming

* delayed projectile spells

* spawn on self + entityEffect on self spells

* spawn on point spell

* rename

* clean up base species components

* magic alert

* move magic energy to Shared, add manacost to spells

* magic recoil

* improve magic recoil

* verbal aspect

* somatic aspect

* add simple vfx proto and sprites

* add casting VFX

* add TODO
2024-07-28 17:26:47 +03:00
PJBot
fce5269fc0 Automatic changelog update 2024-07-28 08:33:32 +00:00
Jona-K
2951ea2bee Adjustet MobBaseAncestor class (#30424) 2024-07-28 01:32:26 -07:00
Plykiya
79fa810b9c Update stomach removal and lung removal smite to not use Component.Owner (#29927)
* Update stomach removal and lung removal smite

* New function makes things simple

---------

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-28 01:25:40 -07:00
PJBot
ab84eee083 Automatic changelog update 2024-07-28 06:18:12 +00:00
Plykiya
1d55a439ff Make NoSlip component networked (#30425)
Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-27 23:17:06 -07:00
Brandon Hu
4a9bd17a86 tweak(geras): Add a confirmation popup for gera transformation (#29215)
* tweak(geras): Add a confirmation popup for gera transformation

* remove abstract parent
2024-07-28 14:13:15 +10:00
PJBot
d9286dd6d9 Automatic changelog update 2024-07-28 03:50:12 +00:00
lzk
e1e2d26969 Fix pancakes stacks (#30270)
Fix pancakes
2024-07-28 13:49:06 +10:00
deathride58
3a10ffa030 Makes the labeller automatically label PRs with shader changes (#30316)
adds shader label to git labeller
2024-07-28 13:46:22 +10:00
metalgearsloth
404743f073 Fix examine threading issues (#30160) 2024-07-28 13:43:59 +10:00
IProduceWidgets
925d1e3ac8 Prevent gridfill from leaking (#30395)
dont forget to set the airtights when the tights are aired
2024-07-28 13:20:29 +10:00
Plykiya
7f9e06501f Update SharedDoorSystem.cs to not use Component.Owner (#29963)
* Update SharedDoorSystem.cs

* comment

* empty space

---------

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-28 13:18:12 +10:00
PJBot
255b7f3b7a Automatic changelog update 2024-07-28 03:15:24 +00:00
metalgearsloth
093054f7e3 Move vgroid much closer (#29943)
* Move vgroid much closer

General feedback is map spam + it takes too long to get to. This is somewhat "close" (considering 1/4 of the distance is the vgroid itself) but without a jetpack / shuttle it's going to be an endeavour.

* Decrease max

* Tweaks

* godzilla

* Update Content.Server/Shuttles/Components/GridSpawnComponent.cs
2024-07-28 13:14:18 +10:00
github-actions[bot]
e3d7c1bd6e Update Credits (#30420)
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
2024-07-27 21:36:00 -04:00
PJBot
845fa31419 Automatic changelog update 2024-07-27 23:12:34 +00:00
Spessmann
34a7aa70ce Thief objectives for figurines and stamps ask for less items (#30390)
Makes thief objective for stealing figures and stamps easier
2024-07-28 02:11:26 +03:00
Brandon Hu
3283424ba8 tweak(Radiation Suits): Increase damage taken by 1000% (#30392)
wtf is 0.9% anyways
2024-07-28 02:10:07 +03:00
Brandon Hu
54e42cc4e5 tweak(NuclearBomb Keg): Give the nuclear bomb keg a hit box (#30415)
* bleh

* Bugs spread disease :(

* they are reproducing

* no lore
2024-07-27 21:45:53 +01:00
Flareguy
9bd623a927 Makes security a bit brighter (#30369)
makes sec more red
2024-07-27 13:51:10 -06:00
Brandon Hu
d846a621e5 tweak(Core_map_Jobslots): Increase round start chemist slots from 1 to 2 (#30408)
that is odd
2024-07-27 13:49:05 -06:00
Brandon Hu
dc1be42b8f tweak(Chemical Dispenser): Give the chemical dispenser a hitbox (#30412)
weh
2024-07-27 21:47:38 +03:00
PJBot
6a1efebb6a Automatic changelog update 2024-07-27 15:09:56 +00:00
BombasterDS
de7df2a760 Some plant mutations (#28993)
* Some new plants mutations

* glasstle inhand

* gapple trico increase ↑

1-10 to 3-16

* replace trico with doc delight
2024-07-27 18:08:49 +03:00
Errant
f49fc5a89c Do not duplicate Job Greeting on antag selection (#30407)
Silence MindAddRoles in AntagSelectionSystem
2024-07-27 07:58:19 -07:00
deltanedas
f67f7034b9 fix ninja not showing in round end (#30405)
fix ninja not showing in round ned

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-07-27 05:08:12 -07:00
Chief-Engineer
b66c286ecb Include whitelisting location in baby jail deny message (#30373)
include whitelist locating in baby jail deny message
2024-07-27 04:49:02 -05:00
PJBot
9f6e5e8d60 Automatic changelog update 2024-07-27 07:28:28 +00:00
Plykiya
1146f2fefe Fix thieves rule not selecting more than one thief (#30393)
More thieves

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-27 00:27:21 -07:00
IProduceWidgets
b9090e84f7 Update Evac-Accordia (#30389)
Update accordia atmos systems
2024-07-26 23:40:39 -06:00
IProduceWidgets
45a481de47 Oasis updoot (#30388)
updoot!
2024-07-26 23:39:43 -06:00
PJBot
5485ae25e0 Automatic changelog update 2024-07-27 04:10:29 +00:00
Golden Can
1149290825 Security Clown Mask (#30249)
Added Security Clown Mask available from hacked SecDrobes.
2024-07-27 00:09:23 -04:00
PJBot
d5d8c14ced Automatic changelog update 2024-07-27 01:55:44 +00:00
metalgearsloth
8f250581be Fix VGRoid grid spam (#29946)
Specifically if a grid splits under the cvar size it doesn't get a label. This also stops stuff like shuttles splitting in half creating new entries for the new grids. Splitting code leaves the largest grid as the existing one so this will always prefer to keep it large (but if there's multiple splits it won't adjust).
2024-07-27 11:54:38 +10:00
PJBot
e7aa7791b4 Automatic changelog update 2024-07-26 18:49:09 +00:00
themias
7c7f4a9f25 Fix zombie uncuffing (#30321)
* Fix zombie uncuffing

* PlaceNextTo() and rename vars
2024-07-26 14:48:03 -04:00
chavonadelal
582e6d2010 Localization of the title of the job (#30353) 2024-07-26 14:47:07 -04:00
Brandon Hu
b1d5436bcd fix(ExtinguisherCabinet): Fix cabinet whitelist to allow fire extinguishers again (#30371)
ugh

Co-authored-by: Avery Dobbins <avery.dobbins@gmail.com>
2024-07-26 14:46:40 -04:00
PJBot
18506e1f3b Automatic changelog update 2024-07-26 17:31:57 +00:00
themias
e72393df71 Fix arcade machines (#30376) 2024-07-26 10:30:49 -07:00
Errant
eab5030c39 Add vox naming convention to Rules (#30284)
vox naming conventions
2024-07-26 10:19:12 -05:00
PJBot
811da0e3d6 Automatic changelog update 2024-07-26 13:00:50 +00:00
Errant
a7fa66e956 Replayspawn logic fix (yes, again) (#30273)
* Fix replayghost spawn

* missed a spot
2024-07-26 13:59:42 +01:00
PJBot
f083d080f5 Automatic changelog update 2024-07-26 06:48:26 +00:00
Moomoobeef
5905767ce7 changed some radio colors to be more distinguishable (#30133)
* changed some radio colors to be more distinguishable

* changed sec, supply, and engineering in order to provide more accessability to deuteranomaly

* the previous commit made engi and supply hard to distinguish again. so I fixed it
2024-07-25 23:47:20 -07:00
Brandon Hu
a99ae6211d fix(cmd-Jobwhitelistadd): Fixed typo in Loc.GetString (#30355)
LET ME IN THE BAR LET ME IN THE BAR LET ME IN THE BAR. IM 18 I SWEAR PLEASE PPLEASE NOOOO I SWEAR PLEASE PLEASE I WANNA GET CRUNK
2024-07-25 23:55:44 -06:00
PJBot
76096b21f1 Automatic changelog update 2024-07-26 05:27:11 +00:00
Cojoke
333bb386d9 Add Identity Blocker to a Couple Things (#30305) 2024-07-25 23:26:04 -06:00
Brandon Hu
4e1fe975ec tweak(StatusIcons): Hide revolutionary icons in the dark. (#30367)
Wilma? eye harley no er
2024-07-25 23:25:33 -06:00
Brandon Hu
44199991bf twek(BoxStation): Reorganize atmos TEG room to be more user friendly. (#30368)
ugh
2024-07-25 23:06:31 -06:00
PJBot
af47cbd7b0 Automatic changelog update 2024-07-25 23:39:00 +00:00
Ilya246
d5236d8236 give nukie reinforcements full operative gear (#30173)
* rebase master

* free fish

* introduce recommended changes

* fix prototypes

* fix protos yet again

* fkhsdjbhehbo;ehb

* rafle
2024-07-25 16:37:54 -07:00
PJBot
ff581d4275 Automatic changelog update 2024-07-25 23:27:14 +00:00
Plykiya
0a07203121 Lets atmos build gas pipes in walls (#28707)
Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-25 16:26:06 -07:00
lzk
818f43b005 Update Meta (#30348)
fans
hardsuits
2024-07-25 15:58:39 -06:00
lzk
d1663cade4 Update Omega (#30356)
* Update Omega

fans
external airlocks
tree escape pods

* remove invalid
2024-07-25 13:48:06 -06:00
lzk
769967ac36 Update Packed (#30358)
fans
external airlocks
2024-07-25 13:15:50 -06:00
lzk
6f7719011a Update Saltern (#30357)
fans
2024-07-25 13:15:28 -06:00
lzk
e161a021c4 fix the bigest news admin notification typo in the game (#30349)
Fix typo
2024-07-25 15:02:15 +01:00
Plykiya
2a7883b92e Update vomit organ smite to not use Component.owner (#29926)
* Update vomit organ smite to not use Component.owner

* is this what you want...?

* am I winning, dad?

* update the comment

* we love entity<t>

---------

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-25 05:24:40 -07:00
Plykiya
7388b91ef5 Replace noSpawn: true with categories: [ HideSpawnMenu ] (#30100)
* NOW THAT'S A LOT OF FILES

* categorization

---------

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-25 05:24:00 -07:00
Ed
6f2e1d6d9f Update CP14StationAdditionalMapComponent.cs 2024-07-25 15:07:12 +03:00
PJBot
e95aaef839 Automatic changelog update 2024-07-25 10:53:26 +00:00
timur2011
bcd7a7ad00 Space adder now butcherable, snake drops snake meat (#29629) 2024-07-25 03:52:18 -07:00
lzk
f56e4f6624 Replace some to do with TODO (#30346)
Replace to do with TODO
2024-07-25 11:04:03 +03:00
Ed
99854edc93 MIT BiomeSpawner 2024-07-25 10:59:36 +03:00
Brandon Hu
50ba20c766 fix(bounties): Make winter counts count as a single warm item. (#30306)
https://news.stanford.edu/stories/2020/05/veil-darkness-reduces-racial-bias-traffic-stops
2024-07-24 23:33:22 -06:00
deltanedas
8de6b74e08 fix borg light being on by default (#30342)
Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-07-24 23:30:17 -06:00
Brandon Hu
2d124c5c29 fix(train): Anchor botany machine, add second artifact spawner. (#30309)
https://www.peoplesworld.org/article/free-college-was-once-the-norm-all-over-america/
2024-07-24 23:29:50 -06:00
PJBot
61efd1201e Automatic changelog update 2024-07-25 05:24:58 +00:00
themias
b0cc97fb04 Fix Ripley control panel (#30325) 2024-07-24 23:23:52 -06:00
PJBot
0d12ce54d4 Automatic changelog update 2024-07-25 03:55:58 +00:00
deltanedas
8f6326c3e0 prevent borgs unlocking eachother and robotics console (#27888)
* prevent borgs from using locks

* e

* bru

* a

* blacklist borgs and robotics console

* frogro

* add IsAllowed to EntityWhitelistSystem

* use IsAllowed

* move thing to new LockingWhitelistSystem

* :trollface:

* review

* use renamed CheckBoth in locking whitelist

* remove unused stuff and add more to doc

* Use target entity instead to remove self check

* Rename to _whitelistSystem

* Add deny lock toggle popup

* Prevent duplicate checks and popups

* Fix wrong entity in popup when toggling another borg

* Make new event

* Update comment to user for new event

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>
2024-07-25 13:54:51 +10:00
marbow
b6811d3570 Medical borg add chem glasses (#27843)
* Update borg_chassis.yml

* Update borg_chassis.yml

* fix

* Removing unnecessary components and adapting changes (#28391) for the syndicate

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
2024-07-25 13:49:32 +10:00
IProduceWidgets
06d136698c Perma escape crate fills and spawner (#29497)
* perma escape crate fills and spawner

* also include maints closets because thats easy.

* oopsie daisys

* green glowsticks

* mindshield

* base folder

* mob traps.

* I skill issued a ctrl+F and wrote garabge into yml

* re work syndicate gift crate, remove ability to get syndicate guns randomly.

* Do mob traps differently to hopefully appease tests.

* mindshield probability decrease.

* lower mob chance since I forgor there are crabs in the walls

* Suffixes

* mob chance was definitely too low.

* still too low

* still a bit low

* that feels right.

* too many mk's

* increase hatchet chance since you need a cutting impliment to logs.

* alphabetize
2024-07-24 20:31:54 -06:00
Ed
50e042011d direct 2024-07-25 00:09:58 +03:00
PJBot
54e760088a Automatic changelog update 2024-07-24 20:58:54 +00:00
Cojoke
620aed5939 Fix QSI Link Range (#30332) 2024-07-24 13:57:45 -07:00
lzk
f210325460 Update Atlas (#30331)
* Update Atlas

connect missed atmos devices (part of #29025)
replace fans in fridge

* remove invalid
2024-07-24 14:52:34 -06:00
lzk
9def96d762 Update Box (#30329)
* Update Box

replace missed tiny fans with directional

* add two more security hardsuits
2024-07-24 14:17:29 -06:00
lzk
687e2c5844 Update Fland (#30330)
replace tiny fans with directional
connect missed external airlocks
2024-07-24 14:12:55 -06:00
lzk
bd4020bdfc Update Cluster (#30327)
replace tiny fans in fridge
2024-07-24 14:12:28 -06:00
lzk
ee641c2dff Update Marathon (#30328)
fans
external airlocks
one escape pod
more airlocks in arrivals
2024-07-24 14:12:21 -06:00
lzk
4536a527df Update Bagel (#30326)
replace tiny fans
fix #29482
2024-07-24 14:11:42 -06:00
Brandon Hu
492fb529df fix(Meta): Resolve every issue. (#30308)
* https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4369587/

* https://www.epa.gov/indoor-air-quality-iaq/what-epas-position-childrens-exposure-secondhand-smokeaerosol
2024-07-24 14:01:24 -06:00
osjarw
aa886ca494 Make NeedHand modifiable for injectorSystem (#29870)
* Get needhand from yml

* MovementThreshold modifiable + inheritdoc
2024-07-24 12:26:52 -07:00
Ed
08f1aa9fa1 Crew goals update (#355)
* randomization goals support

* maps update
2024-07-24 20:52:05 +03:00
Nim
bb20f3a1bc fix Mannequin (#354) 2024-07-24 19:14:18 +03:00
Brandon Hu
c4dcc90972 tweak(GunRequiresWield): State the requirement for gun wielding in the description. (#30301)
* https://en.wikipedia.org/wiki/List_of_LASD_deputy_gangs

* https://knock-la.com/tradition-of-violence-lasd-gang-history/

* https://coc.lacounty.gov/deputy-gangs/
2024-07-24 08:33:14 -04:00
Killerqu00
688a46f903 Move some disabilities traits into a new category (#30102)
split traits into disabilities and quirks
2024-07-24 06:50:19 -04:00
Ed
9c84ce9be0 Currency collect goal (#352)
* simple currency comp

* stack support + weapon cost dnd port

* add collect currency objective conditions

* clean up
2024-07-24 13:28:27 +03:00
Brandon Hu
343496faf8 tweak(chameleon): Add clown suit to chameleon tech (#29307) 2024-07-24 02:04:20 -07:00
PJBot
fc0954085f Automatic changelog update 2024-07-24 08:58:11 +00:00
BombasterDS
8b27ef8a78 Fix: Shelfs and Mannequin disassemble (#30313)
fix shelfs
2024-07-24 01:57:03 -07:00
Ed
bf93349b73 Female bodies support (#350)
* port female parts

* boobs support!

* tiefling boobs confirmed

* Update female_shirt.png

* Update female_shirt.png
2024-07-24 09:11:31 +03:00
mkanke-real
e1f3bdc748 Add spicy rock pizza (#30116)
* Added all the parts to implement spicy rock pizza

* Added sprites for pizza

* Fixed coma formatting in meta.json for pizzas

* Fix formatting and rebalance reagent quantities in pizza.yml

* Flipped Uranium and Radium values to be the correct ratio

* Updated meta.json file to have credit for sprite
2024-07-23 16:22:11 -07:00
PJBot
4f8b634f38 Automatic changelog update 2024-07-23 21:03:13 +00:00
Benjamin Velliquette
a32f9ff711 Fix Reagent Grinder being able to do work without being powered (#30267)
* Check if grinder is powered before doing work

* Use existing extention method.
2024-07-23 14:02:07 -07:00
Ed
c5a6f75def Merge pull request #348 from crystallpunk-14/ed-23-07-2024-upstream
Ed 23 07 2024 upstream
2024-07-23 22:01:51 +03:00
Ed
8c477a67c1 Update centcomm.yml 2024-07-23 21:50:00 +03:00
Ed
3b5e0003c3 Create centcomm.yml 2024-07-23 21:45:41 +03:00
Ed
ea753e5227 Update PostMapInitTest.cs 2024-07-23 21:17:41 +03:00
PJBot
ec071ceca7 Automatic changelog update 2024-07-23 17:48:15 +00:00
Scribbles0
7381df4335 Handless mobs can no longer wipe devices (#30149)
add check for hands
2024-07-23 10:47:07 -07:00
Ko4ergaPunk
e7aa97645b Change drawdepth of some wall-mounted objects (#30274)
drawdepth
2024-07-23 17:41:15 +03:00
Ed
3187006641 disable NukeOps test 2024-07-23 14:19:28 +03:00
Ed
526238bac5 fix 2024-07-23 14:04:13 +03:00
Ed
f348213750 Update arenas.yml 2024-07-23 13:46:57 +03:00
Ed
ed3e896cb8 Update debug.yml 2024-07-23 13:40:19 +03:00
Ed
0190e366a3 maps fix 2024-07-23 13:27:58 +03:00
Ed
9826b9ff38 Update goblin.yml 2024-07-23 13:16:49 +03:00
Tornado Tech
86b746217d Fix all shit 2024-07-23 20:12:10 +10:00
Ed
17d0e6326e Create cp14-ignoredPrototypes.yml 2024-07-23 12:51:48 +03:00
Ed
ab8655040b Update InventoryComponent.cs 2024-07-23 12:34:48 +03:00
Ed
f71dffb746 update displacements 2024-07-23 12:30:49 +03:00
Ed
2367085160 Merge remote-tracking branch 'upstream/master' into ed-23-07-2024-upstream
# Conflicts:
#	.github/PULL_REQUEST_TEMPLATE.md
#	Content.Client/Clothing/ClientClothingSystem.cs
#	Content.Client/Hands/Systems/HandsSystem.cs
#	Content.IntegrationTests/Tests/PostMapInitTest.cs
#	Content.Shared/Hands/Components/HandsComponent.cs
#	Content.Shared/Inventory/InventoryComponent.cs
#	Content.Shared/Storage/StorageComponent.cs
#	Resources/Prototypes/Accents/word_replacements.yml
#	Resources/Prototypes/Entities/Mobs/Player/human.yml
#	Resources/Prototypes/Maps/Pools/default.yml
#	Resources/Prototypes/Maps/fland.yml
#	Resources/Prototypes/Maps/oasis.yml
#	Resources/Prototypes/Maps/packed.yml
#	Resources/Prototypes/Maps/saltern.yml
2024-07-23 12:24:42 +03:00
Ed
918709cb47 Displacement maps big update (#30093)
* split logic into own system

* add support for different size displacement maps

* some clothes may not use displacement maps

* displacement maps spport hand sprites

* Update DisplacementMapSystem.cs

* rename things

* fuck stencilmask

* fix bugs

* no masks

* Update jumpsuits.yml

* fix species specific sprites

* Update ClothingSystem.cs

* shoes + ears displacement, some bugfix

* Update DisplacementMapSystem.cs
2024-07-23 12:04:09 +03:00
Tornado Tech
e806655c9d Wave shader WIP (#288)
* Created wave shader

* more to _CP14 folders

* add to tree

* fix

* pipiipi

* Provided shader uniform to component fields

* Fixed wave shader shit

* goodies

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
Co-authored-by: Ed <edwardxperia2000@gmail.com>
2024-07-23 11:27:09 +03:00
lzk
4ff34458cf Lowercase some prototypes names (#29990)
* Lowercase some prototypes names

* huh

* return altar

* apply

* meta map
2024-07-23 11:16:11 +03:00
PJBot
629cd432b9 Automatic changelog update 2024-07-23 08:14:25 +00:00
TheKittehJesus
1f29a5ad36 Fix: Syndie borg can now wield DEsword (#30229)
* Syndie borg can now wield DEsword

* Made child of EnergySwordDouble for borgs
* Made ESword borg module use this new borg DESword

* Removed name property of CyborgDESword so that it now inherits from DESword and added a suffix to differentiate the two in spawn menu
2024-07-23 01:13:18 -07:00
Ed
9f1b4fc51c Melting molds (#347)
* temp tweak

* add metall bars

* melting molds

* add sawing molds table

* sawing sounds

* fix
2024-07-23 10:29:41 +03:00
PJBot
046aa54d0d Automatic changelog update 2024-07-23 06:37:13 +00:00
Errant
eb861d173f Wrong magazine popup (#29046)
* wrong magazine

* a single typo

* removed GunSystem solution

* magazine misfit warnings
2024-07-22 23:36:05 -07:00
PJBot
99c3341dc9 Automatic changelog update 2024-07-23 03:24:10 +00:00
Cojoke
3ab6d5daff Makes the QSI Popup Nicer (#30265) 2024-07-22 20:23:04 -07:00
PJBot
d65c78746e Automatic changelog update 2024-07-23 02:34:47 +00:00
Cojoke
2d4aaa414f telescreen and television require vision + Move eye to shared (#30260)
* telescreen and television require vision

* Move Content.Server.Eye to Shared

* fix popups

* Filthy
2024-07-22 19:33:41 -07:00
Plykiya
851a0e15a7 fix crayon (#30263)
Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-23 12:22:59 +10:00
PJBot
768aeb28ec Automatic changelog update 2024-07-23 02:19:39 +00:00
Flareguy
8376881cdf Minor vox headwear update (#30150)
* vox sprites minor updates

* the tax

* kid named paper sack
2024-07-23 12:18:32 +10:00
PJBot
064b52a5ed Automatic changelog update 2024-07-22 22:25:32 +00:00
Cojoke
e039e92016 Fix Freezing on throwing jetpack (#30223)
* Fix Freezing on throwing jetpack

* bweep(requested stuff)
2024-07-22 18:24:26 -04:00
PJBot
6bd1604194 Automatic changelog update 2024-07-22 21:42:48 +00:00
Cojoke
88cc6753ea Adds the Volume of a Gas Tank to its Examine Text (#29771)
* Adds the Volume of a Gas Tank to its Examine Text

* Put Volume in description

* Put Volume in description

* work please?

* Hit space bar
2024-07-22 14:41:42 -07:00
Jezithyr
99492e3e3f Added fixedpoint 4 (#29834)
* Added fixedpoint 4, which is basically just fixedpoint2 but with 4 points of precision and using a long instead of an int to store values.
2024-07-22 14:07:31 -07:00
PJBot
65f9cc3155 Automatic changelog update 2024-07-22 19:33:36 +00:00
Errant
bf1450fdc8 Fix replayghost spawning location (#30252)
Fix replayghost spawn
2024-07-22 20:32:30 +01:00
MerrytheManokit
61fd8167e0 Istg, rq, and dw (#30216)
* Update word_replacements.yml

* Update speech-chatsan.ftl
2024-07-22 19:53:34 +01:00
GrandApothecary19
fee5cc25ce Deleting all CP14 guns proto (#346)
* Deleting all CP14 guns proto

* sprites deleting to
2024-07-22 19:11:07 +03:00
Ed
a81465f0d9 Rock and stone mini update (#344)
* ore resprite

* tools restruct, ore repath, add pickaxr

* fixes

* localizattion sync

* fixes

* Update migration.yml
2024-07-22 18:46:26 +03:00
PJBot
b6f3545c8c Automatic changelog update 2024-07-22 10:21:42 +00:00
osjarw
d8433a8f86 Make delay incurred from additional syringe contents modifiable + tiny syringe buff/fix (#29825)
* Make delay incurred by transfer amount modifiable

* No unintentional negative delay please

* Use more fixedpoint, hope I didn't break anything

* merge review suggestion

Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>

---------

Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>
2024-07-22 03:20:36 -07:00
lzk
cac867fa6d improve info about 🆑 symbol in pr template (#30204)
* Improve PR template

* fix typo
2024-07-22 12:56:48 +03:00
3nderall
159a7413a7 Stops foam counting as a connection for walls (#30236)
Stops walls from connecting to foam

Co-authored-by: 3nderall <3nderall@gmail.com>
2024-07-22 12:55:44 +03:00
PJBot
1c43f85ffe Automatic changelog update 2024-07-22 09:55:21 +00:00
Plykiya
edd9bb6e74 Quieter bag sounds (#30225)
Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-22 12:54:15 +03:00
PJBot
183d26f001 Automatic changelog update 2024-07-22 09:34:08 +00:00
IProduceWidgets
9bc9b6b696 Amend spacelaw to allow zookeepers to have tranq shotguns. (#30237)
In loving memory of Harambe May 27, 1999 – May 28, 2016
2024-07-22 04:33:02 -05:00
PJBot
28c8eba330 Automatic changelog update 2024-07-22 09:19:03 +00:00
Gagarinten-Noverdo
cb3c6b555a Selfdamage for melee (#85) (#342)
* Selfdamage for melee.

* Update base.yml

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
2024-07-22 12:18:08 +03:00
Plykiya
1aa2410f4e Eating and Drinking Doafter Change (#30060)
My lawyer told me to do this

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-22 02:17:57 -07:00
Ed
f91a642428 Workbench (#341)
* craft prototype

* comp + empty system

* simple crafting

* 2 crafts!

* craft dound + delay

* ingredient waste

* verb message

* stack support

* sprite + collision + real crafts

* workbench craft

* fuck

* Update CP14WorkbenchSystem.cs

* fuck ItemPlacer, _lookup lets go
2024-07-22 12:16:32 +03:00
PJBot
4e34fb66ec Automatic changelog update 2024-07-22 05:40:03 +00:00
LankLTE
395b296d68 Darts can now pop balloons. (#30088)
Basic implementation.
2024-07-21 22:38:56 -07:00
PJBot
1fa91e2785 Automatic changelog update 2024-07-22 03:56:42 +00:00
slarticodefast
4eed2fd973 fix borgs being unable to state laws with an active flashlight (#30183)
fix borg laws
2024-07-22 13:55:34 +10:00
justdie12
290542534a Update water.yml (#29596)
* Update water.yml

Water should put out the fire. That's why now the water tiles are extinguishing you.

* Update water.yml
2024-07-22 12:53:10 +10:00
slarticodefast
a0aafdfedd vital clown bugfix PR (#30243)
vital bugfix
2024-07-21 19:50:21 -07:00
Ed
4a6a76fc06 Merge pull request #343 from Pelemonk/test
Добавление нового питомца "Железный защитник"
2024-07-22 02:00:52 +03:00
Pelemonk
f8428d636d irondog 2024-07-21 20:59:34 +03:00
Pelemonk
05e676fb98 Update pets.yml 2024-07-21 20:53:39 +03:00
Pelemonk
5cef8ca104 Revert "Update dwarf.yml"
This reverts commit fda3af5030.
2024-07-21 20:52:02 +03:00
Pelemonk
faeb3f1b91 Revert "Update dwarf.yml"
This reverts commit 88b6b457df.
2024-07-21 20:51:41 +03:00
Pelemonk
177112b216 Заменен Walter на Doggi 2024-07-21 20:43:14 +03:00
PJBot
73024fc69f Automatic changelog update 2024-07-21 17:18:04 +00:00
Sphiral
1e89c07573 The Shelfs Update (#27858)
* goofed up

* wip, mostly test sprites

* Nearly done, just need to fix storage locks

* everything done to my knowledge

* Alright, construction tested and working, and updated health spread

* remove a single comment I forgot. Pending sprite changes.

* Update sprites and add chemistry locked preset

* Forgot to remove a comment
2024-07-21 11:16:58 -06:00
Pelemonk
88b6b457df Update dwarf.yml 2024-07-21 19:44:36 +03:00
Pelemonk
fda3af5030 Update dwarf.yml 2024-07-21 19:32:53 +03:00
PJBot
b66afb572e Automatic changelog update 2024-07-21 16:21:15 +00:00
slarticodefast
d5bdada430 fix microwave construction (#30232)
* fix microwave construction

* retry
2024-07-21 12:20:09 -04:00
Tayrtahn
3e3cfdb948 Fix error when manually adding ChasingWalkComponent to an entity (#30207) 2024-07-21 12:17:03 -04:00
PJBot
d1ecd84972 Automatic changelog update 2024-07-21 10:47:39 +00:00
Cojoke
1119bc01cf Prevent Dragon Body from Despawning (#29842)
* Prevent Dragon Body from Despawning + Make Dragon Unrevivable

* Requested changes

* Meh, nobody wanted this anyways and it was not really an issue
2024-07-21 20:46:33 +10:00
PJBot
06654c3158 Automatic changelog update 2024-07-21 10:33:32 +00:00
Plykiya
aded74a88a Syndicate Reinforcement Specializations: Medic, Spy, Thief (#29853)
* Syndicate thief, spy, medic

* Fixes description for nukies

* update description for uplink

* Implement the radial menu

* forgot these were necessary to push lol

---------

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-21 20:32:25 +10:00
PJBot
bd302a0ee9 Automatic changelog update 2024-07-21 07:45:25 +00:00
Ed
c407f7c473 Train map fix (#30145)
* train fix

* Update train.yml

* Update train.yml

* Add files via upload

* Revert "Add files via upload"

This reverts commit 9c6c2caae32899e7bef9c45db1ff4317a0dae529.

* Update train.yml
2024-07-21 01:44:18 -06:00
lzk
ddc3e3110e Update Bagel (#30191)
replace tiny fans with derectional fans
link not linked external airlocks to bolting and closing
2024-07-21 01:43:16 -06:00
PJBot
fcf8943c82 Automatic changelog update 2024-07-21 07:29:43 +00:00
osjarw
644736b382 NPCs no longer consider anchored pipes as weapons (#30061)
* Anchored pipes are no longer considered weapons

* Switch to overload utilizing a TransformQuery
2024-07-21 17:28:37 +10:00
IProduceWidgets
c7ff647cb3 Nukie Outpost is no longer a station map (#30090)
* I dunno, break shit I guess.

* Actually fix some shit for once.

* test flakey or me flakey?

* Test were not flakey, they just didnt make any sense anymore.

* more stationy tests

* undo abuncha shit I can set in yml instead

* forgor an assert

* unneeded usings

* 1984

* I made github angy

* yoink

* the end is never the end is never the end is never the end is never the end is never the end is never the

* Im going to commit sudoku
2024-07-21 01:26:30 -06:00
PJBot
564199f0c7 Automatic changelog update 2024-07-21 07:25:35 +00:00
IProduceWidgets
ac53e1d0a0 add an arabian lamp. (#27270)
* add an arabian lamp

* yoink solutionitemstatus since it already displays fuel remaining.

* add comments

* fix containerception?

* Yeah sure, pray- I mean rubable.

* fix one flame frame

* Fixed emag behavior

* me when lexidysia.

* limit capacity of entitystorage and add some more comments about why it be the way it do.

* test fake?

* Holy fuck its a bug fix now? Based.
2024-07-21 01:24:28 -06:00
metalgearsloth
56de41e8a7 Hide escape pods on shuttle map (#29758) 2024-07-21 17:23:44 +10:00
Pissachu
0cb86d7aae Fixing Botanist role numbers in various stations - V2 (#29581) 2024-07-21 01:23:27 -06:00
PJBot
17be5c9782 Automatic changelog update 2024-07-21 07:23:10 +00:00
lzk
673cd8accd Update Cluster and evac (#30003)
* Update Cluster

replace dirty tiles with dirt decals
less visual noise in xenoarch
less visual noise in kitchen
less visual noise in botany
give one more table in kitchen
add screens
close cow crate in kitchen
better floor in cargo
changed floor in bridge conf room
remove few stacked pipes

* Update Cluster Evac

white steel tile under med airlock

* Update Cluster

replace tiny fans with derectional fans
link not linked external airlocks to bolting
2024-07-21 01:23:01 -06:00
Winkarst
ee2e94a204 Fix servers ambience sound (#30091)
* Fix servers ambience

* I'm silly

* Clean up
2024-07-21 17:22:02 +10:00
lzk
354228c4b9 Update Atlas (#30192)
replace tiny fans with derectional fans
link not linked external airlocks to bolting
2024-07-21 01:20:54 -06:00
lzk
40a73db91f Update Box (#30190)
replace tiny fans with derectional fans
link not linked external airlocks to bolting and closing
2024-07-21 01:20:43 -06:00
metalgearsloth
e77ebaf325 Fix war declarator (#30221) 2024-07-21 17:17:59 +10:00
PJBot
170c070443 Automatic changelog update 2024-07-21 07:05:39 +00:00
Alzore
c8725825be Replace the machete and laser in the borg weapons module with an e-dagger and recharging viper (#26947)
* no more lasers for you, borg.

* downgrade

* echis

* echis

* itemtoggleupdate

* daggerparenting

* fixtypo

* more bullet per bullet
2024-07-21 17:04:33 +10:00
PJBot
c22906205e Automatic changelog update 2024-07-21 06:39:50 +00:00
metalgearsloth
b41c6a28fe Reset ghost role menu scroll upon search (#30159)
Quality of life so it doesn't sit on your old spot anymore.
2024-07-21 02:38:45 -04:00
PJBot
5cb0442b75 Automatic changelog update 2024-07-21 06:14:34 +00:00
metalgearsloth
aca878c9f7 Set input coords to invalid if mouse off-screen (#30164)
This may be a breaking change for some stuff, I only tested basic combat stuff + throwing.

This fixes the coordinates setting an off-screen position to the top-left pixel and blocks throw attempts as a result.
2024-07-21 02:13:28 -04:00
PJBot
2c8dd58ad8 Automatic changelog update 2024-07-21 06:10:22 +00:00
metalgearsloth
b4ec629b9f Fix muzzle flash tracking (#30163)
* Fix muzzle flash tracking

User was never set on the networked event but we don't really need it anyway.

* Also this one
2024-07-21 02:09:16 -04:00
PJBot
6bbbba5702 Automatic changelog update 2024-07-21 05:50:54 +00:00
Crude Oil
6c6ae35cf8 Add ability to show stack visuals on closed containers (#29309)
* add ability to show stack visuals on closed containers

* remove container stack visuals logic from sharedstoragesystem

* improve comments a bit

* move logic for open/closed containers into itemcountersystem

* move behavior to storage component

* remove unused import

* remove old comment

* fix comments

* fix wrong property name

* Update Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs

* Rename variable for clarity

---------

Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>
2024-07-20 22:49:48 -07:00
PJBot
b0c4c45bc5 Automatic changelog update 2024-07-21 05:28:24 +00:00
Nemanja
0b5fe2a9ac PA ui cleanup + bugfixes (#28750)
* ui and visual aspect + radio

* finish jank ui shit and finish radio

* remove radio

* send it

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2024-07-21 15:27:18 +10:00
metalgearsloth
edb05e36bb Reapply "Remove some BUI boilerplate" (#30214) (#30219)
* Reapply "Remove some BUI boilerplate" (#30214)

This reverts commit cb0ba66be3.

* Fix gas tank

* Fix PA

* Fix microwave

* Comms console underwrap

* Fix rcd

* log wehs
2024-07-21 14:48:13 +10:00
PJBot
87e52e50b4 Automatic changelog update 2024-07-21 03:30:29 +00:00
buntobaggins
6b57cf2020 Spationaut Hardsuit Light buff (#30049)
Buffed the light on the Spationaut Hardsuit

Co-authored-by: buntobaggins <email.com>
2024-07-20 20:29:21 -07:00
Nemanja
cb0ba66be3 Revert "Remove some BUI boilerplate" (#30214)
Revert "Remove some BUI boilerplate (#28399)"

This reverts commit cbf329a82d.
2024-07-20 20:42:27 -04:00
Chief-Engineer
6d664c9157 Add debug logs to baby jail and fix playtime logic (#30158)
* add debug logs

* Update Model.cs

* fix playtime logic for null playtime

* remove unnecessary condition

* either me or the compiler is having a C# skill issue
2024-07-21 01:28:43 +02:00
chavonadelal
c89186a26f Localization of encryption keys (#30172)
* Localization of encryption keys

* Localization of encryption keys update
2024-07-20 19:14:41 +03:00
DrSmugleaf
297baaca23 Add user to AttemptMeleeEvent, add ThrowItemAttemptEvent (#30193)
* Add user to AttemptMeleeEvent, add ThrowItemAttemptEvent

* Add xmldoc
2024-07-20 18:06:52 +10:00
JIPDawg
1208928564 Added missing builld components to RCD [empty] (#30177)
* Added missing stuff to rcd[empty]

* do the smart thing

---------

Co-authored-by: JIP <jipdawg93@gmail.com>
2024-07-20 02:23:07 -04:00
IProduceWidgets
3a30eea640 Update oasis (#30182)
* Update oasis

* unpause map. We really need a test for that.

* lv cables

* magic or gate airlock
2024-07-20 00:22:47 -06:00
metalgearsloth
53eb9421c2 Update submodule to 229.0.0 (#30186) 2024-07-20 15:56:34 +10:00
lzk
8d5792efd7 Remove HighImpassable from TableTopLayer (#29455)
* uhmm

* Update CollisionGroup.cs
2024-07-20 15:56:21 +10:00
PJBot
0cbc2e8d43 Automatic changelog update 2024-07-20 05:55:05 +00:00
Aiden
4997f92e18 MassHallucinationsRule Minor Refactor (#28748)
* Update MassHallucinationsRule.

* Update Content.Server/StationEvents/Events/MassHallucinationsRule.cs

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

* Update Content.Server/StationEvents/Events/MassHallucinationsRule.cs

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

* Update Content.Server/StationEvents/Events/MassHallucinationsRule.cs

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

* MGS Change

* Update Content.Server/StationEvents/Events/MassHallucinationsRule.cs

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

* Update Content.Server/StationEvents/Events/MassHallucinationsRule.cs

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

* Move affectedentities to component, remove masshallucinationscomponent as its no longer needed to track entities.

* Apply suggested changes.

* No double checks

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
2024-07-20 15:53:57 +10:00
metalgearsloth
cbf329a82d Remove some BUI boilerplate (#28399)
* Remove some BUI boilerplate

- The disposals overrides got removed due to the helper method handling it.
- Replace window creation with CreateWindow helper.
- Fixed some stinky code which would cause exceptions.

* More

* moar

* weh

* done

* More BUIs

* More updates

* weh

* moar

* look who it is

* weh

* merge

* weh

* fixes
2024-07-20 15:40:16 +10:00
DrSmugleaf
4aba9ec131 Fix NPC line of sight not working if trying to ranged target a blocking entity (#30055) 2024-07-20 13:58:33 +10:00
eoineoineoin
1783e0e4c2 Add a background for OptionsButton popup (#29792)
Add a reasonable background for OptionsButton popup

Co-authored-by: Eoin Mcloughlin <helloworld@eoinrul.es>
Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com>
2024-07-20 13:54:36 +10:00
CaasGit
b04f98513c fix(FaxVisualsSystem): Fax can Play() when a anim key has been added. (#30013)
Adds a check to see if a faxecute animation is being played before
playing another animation. The old code can thrown an exception which
I've seen on live while ghosting.
2024-07-20 13:36:22 +10:00
deltanedas
8be13bf495 fix fish petting misprediction (#30175)
* make fish petting ignore use delay

* m

* troll

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-07-20 13:23:46 +10:00
SlamBamActionman
6972bc26a7 Directional Fans (#27772)
* Initial commit

* Description update

* Updated texture
2024-07-20 13:18:34 +10:00
DrSmugleaf
78f3ffc2a4 Make ActionsSystem.UpdateAction public (#30056) 2024-07-19 23:03:43 -04:00
PJBot
a2b021dffb Automatic changelog update 2024-07-20 03:01:35 +00:00
Plykiya
7683acab5e Fix Chameleon Scarf menu being blank (#30156)
fixa the scarfa

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-19 23:00:28 -04:00
JIPDawg
aedf52f8ec Removed references to pipestacking and changed example setup in Guidebook (#30181)
Removed references to pipestacking and changed example setup

Co-authored-by: JIP <jipdawg93@gmail.com>
2024-07-19 23:00:00 -04:00
Ghagliiarghii
e6b171645c Give NukeOps Reinforcements an ID Card (in a PDA) (#28088)
* Give NukeOps Reinforcements an ID Card (in a PDA)

* add warning comment

* create syndicateoperativegeatreinforcementnukeops in traitor.yml

* revert fun/misc_startinggear.yml
2024-07-20 12:59:31 +10:00
PJBot
93eeab2d10 Automatic changelog update 2024-07-20 02:32:34 +00:00
themias
5dfca4c2dc Fix mailing unit UI (#30174) 2024-07-20 12:31:26 +10:00
PJBot
3c7d14ad50 Automatic changelog update 2024-07-19 14:19:45 +00:00
DakotaGay
f2b9cd7a25 Fix Markup Tags in Station News (#30169)
* Fix (hopefully)

* Fixed Spelling Mistake and minor Code Cleanup

* Revert "Fixed Spelling Mistake and minor Code Cleanup" due to Pull Request Guidelines

This reverts commit cee3e0226b349187bd8fd8b639e161fb877e8bdb.
2024-07-19 10:18:39 -04:00
PJBot
58e5a7a668 Automatic changelog update 2024-07-19 09:44:04 +00:00
slarticodefast
eaace152ae Fix EmbeddableProjectileComponent and ThrowingAngleComponent interaction (#30112)
* fix embeddable offset with throwing angle

* number
2024-07-19 19:42:58 +10:00
PJBot
e7911c3720 Automatic changelog update 2024-07-19 09:39:32 +00:00
Alzore
93dc22b67d Add the Syndicate Raid Suit (#29845)
* Syndicate Raid Suit

* Raid suit speed and whitelist

* Fix copyright for the syndicate raid helmet
2024-07-19 12:38:26 +03:00
PJBot
c4b6917cfc Automatic changelog update 2024-07-19 09:05:50 +00:00
deepdarkdepths
b8ee458188 Remove geras description in Slime Person guidebook page (#30140)
remove entry
2024-07-19 12:04:43 +03:00
Ed
a7f1dfaec4 Merge pull request #338 from crystallpunk-14/ed-19-07-2024-upstream-walls
Ed 19 07 2024 upstream walls
2024-07-19 11:35:48 +03:00
Ed
ca843bd84a Merge remote-tracking branch 'upstream/master' into ed-19-07-2024-upstream-walls
# Conflicts:
#	Content.Server/Damage/Systems/DamageOtherOnHitSystem.cs
2024-07-19 11:23:38 +03:00
Ed
c8a90a74c0 Update ContentLocalizationManager.cs 2024-07-19 11:20:34 +03:00
Ed
d6e0114126 randomize iconSmoothing (#28158)
* randomize iconSmoothing

* Revert "randomize iconSmoothing"

This reverts commit 094356f975737c0af24ce39d849aec7852b9af6e.

* try 2

* trying work with client-server communication

* still dont work

* Tayrtahn good suggestion

* remove outdated code

* Fix!

* move data to Appearance

* Update RandomIconSmoothComponent.cs
2024-07-19 18:13:35 +10:00
metalgearsloth
6005a9f4cb Fix door access in mapping mode (#30030)
Fix shouldn't break anythingTM.
2024-07-19 16:19:15 +10:00
PJBot
56ee4da535 Automatic changelog update 2024-07-19 01:10:01 +00:00
Plykiya
6d18dff33d Fix for thrown items dealing damage twice to first target (#30115)
* FUCK YOU

* fine

---------

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-18 21:08:52 -04:00
Cojoke
b57174007c Remove all Assigned Values that are Never Used (#30110)
Remove all Assigned Values that are never used
2024-07-18 20:22:23 -04:00
Plykiya
84fe6bcde4 Fix arrow pointing animation (#30134)
Fixa the arrows

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-18 20:21:01 -04:00
PJBot
d30b45f23f Automatic changelog update 2024-07-18 22:37:59 +00:00
portfiend
3ef5f521e2 fix: give reptilians species mask sprites in lobby (#30095) 2024-07-19 01:36:53 +03:00
PJBot
0c2b569622 Automatic changelog update 2024-07-18 22:35:26 +00:00
Smirnov Peter
2fb2cde125 Add item checking for moth food (#30019)
* Add ContainerContainer component checking for moth food

* Use ItemSlotsComponent checking on food item
2024-07-19 01:34:18 +03:00
Ed
2bf17fdc35 Content pack (#337)
* added rope

* black shirt replace

* Update migration.yml

* more berets

* loadout update

* captain role and jacket

* bruhh captain cap

* add one-handed sword

* shield!

* Update entities.ftl
2024-07-19 00:03:08 +03:00
Ed
dec6a1c2ca Ru localization update (#335)
* Update entities.ftl

* Update ContentLocalizationManager.cs

* Update ContentLocalizationManager.cs

* Update entities.ftl
2024-07-18 23:40:06 +03:00
Ed
437fc936a2 LatheSystem independently of energy (#30148)
* Update LatheSystem.cs

* Emo
2024-07-18 22:29:20 +03:00
slarticodefast
a94f1f0fe0 Correct .editorconfig to use no space after casting (#30132) 2024-07-18 10:43:20 -08:00
Jaraten
77b1113d5d Walls upd (#333)
* wewe

* oops

* oooopsss 2
2024-07-18 16:11:59 +03:00
Brandon Hu
73111b5170 fix(dev_map): resave dev map (#30098)
fix(dev_map): Resave devmap

Co-authored-by: 4llv07e <igor@c4llv07e.xyz>
2024-07-18 10:17:57 +03:00
PJBot
58a2a4c932 Automatic changelog update 2024-07-18 00:49:15 +00:00
Plykiya
961a553fa2 Fix stun batons using excess charges when thrown (#30136)
Fix stun batons

Co-authored-by: plykiya <plykiya@protonmail.com>
2024-07-18 10:48:08 +10:00
PJBot
d7b2e72882 Automatic changelog update 2024-07-18 00:42:02 +00:00
slarticodefast
3f014e84eb minor SharedInteractionSystem cleanup (#30139)
cleanup SharedInteractionSystem
2024-07-18 10:41:15 +10:00
Cojoke
95b56ad4ce Prevent Quantum Spin Inverter from Teleporting Things into Microwaves (#29200)
* Prevent Quantum Spin Inverter from Teleporting Things into Microwaves

* Simplifies code, GetTeleportingEntity instead of TryGet, adds failed teleport message

* remove using Linguini.Syntax.Ast;

* capital...

* re-add CanInsert and Fixes microwave issue

* beb

* beeb
2024-07-18 10:40:54 +10:00
kbailey-git
c7ea0490a6 Updated slime storage capacity text in guidebook (#30121) 2024-07-17 15:54:08 -07:00
Ed
e1f429b6b3 DungeonSystem.Rooms bugfix (#30125)
Update DungeonSystem.Rooms.cs
2024-07-17 18:37:03 -04:00
PJBot
2d5bb92f46 Automatic changelog update 2024-07-17 22:05:58 +00:00
Errant
ef02f8c18c Temporarily remove Vox from space ninja and Unknown Shuttle ghostroles (#30099)
* no vox ninjas

* blacklist vox from UnknownShuttleEvent
2024-07-18 01:04:51 +03:00
1259 changed files with 121613 additions and 54581 deletions

View File

@@ -129,7 +129,7 @@ csharp_indent_braces = false
csharp_indent_switch_labels = true
# Space preferences
csharp_space_after_cast = true
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false

View File

@@ -7,11 +7,11 @@
<!-- Зачем нужно это изменение? Прикрепите любые обсуждения или проблемы здесь. Опишите, как это повлияет на текущий баланс игры. -->
## Media
<!--
<!--
PRs which make ingame changes (adding clothing, items, new features, etc) are required to have media attached that showcase the changes.
Small fixes/refactors are exempt.
-->
<!--
<!--
Пулл реквесты, которые несут за собой игровые изменения (добавления одежды, предметов и так далее) требуют чтобы вы прикрепили скриншоты или видеоролики, демонстрирующие эти изменения.
Небольшие исправления не считаются.
-->

4
.github/labeler.yml vendored
View File

@@ -12,6 +12,10 @@
- changed-files:
- any-glob-to-any-file: '**/*.xaml*'
"Changes: Shaders":
- changed-files:
- any-glob-to-any-file: '**/*.swsl'
"No C#":
- 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.

View File

@@ -2,6 +2,7 @@ using Content.Shared.Access;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Containers.ItemSlots;
using Robust.Client.UserInterface;
using Robust.Shared.Prototypes;
using static Content.Shared.Access.Components.AccessOverriderComponent;
@@ -23,6 +24,28 @@ namespace Content.Client.Access.UI
{
base.Open();
_window = this.CreateWindow<AccessOverriderWindow>();
RefreshAccess();
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
_window.OnSubmit += SubmitData;
_window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId));
}
public override void OnProtoReload(PrototypesReloadedEventArgs args)
{
base.OnProtoReload(args);
if (!args.WasModified<AccessLevelPrototype>())
return;
RefreshAccess();
if (State != null)
_window?.UpdateState(_prototypeManager, (AccessOverriderBoundUserInterfaceState) State);
}
private void RefreshAccess()
{
List<ProtoId<AccessLevelPrototype>> accessLevels;
if (EntMan.TryGetComponent<AccessOverriderComponent>(Owner, out var accessOverrider))
@@ -30,38 +53,20 @@ namespace Content.Client.Access.UI
accessLevels = accessOverrider.AccessLevels;
accessLevels.Sort();
}
else
{
accessLevels = new List<ProtoId<AccessLevelPrototype>>();
_accessOverriderSystem.Log.Error($"No AccessOverrider component found for {EntMan.ToPrettyString(Owner)}!");
}
_window = new AccessOverriderWindow(this, _prototypeManager, accessLevels)
{
Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName
};
_window.PrivilegedIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(PrivilegedIdCardSlotId));
_window.OnClose += Close;
_window.OpenCentered();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_window?.Dispose();
_window?.SetAccessLevels(_prototypeManager, accessLevels);
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
var castState = (AccessOverriderBoundUserInterfaceState) state;
_window?.UpdateState(castState);
_window?.UpdateState(_prototypeManager, castState);
}
public void SubmitData(List<ProtoId<AccessLevelPrototype>> newAccessList)

View File

@@ -13,26 +13,24 @@ namespace Content.Client.Access.UI
[GenerateTypedNameReferences]
public sealed partial class AccessOverriderWindow : DefaultWindow
{
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private readonly AccessOverriderBoundUserInterface _owner;
private readonly Dictionary<string, Button> _accessButtons = new();
public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototypeManager prototypeManager,
List<ProtoId<AccessLevelPrototype>> accessLevels)
public event Action<List<ProtoId<AccessLevelPrototype>>>? OnSubmit;
public AccessOverriderWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
var logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill);
}
_owner = owner;
public void SetAccessLevels(IPrototypeManager protoManager, List<ProtoId<AccessLevelPrototype>> accessLevels)
{
_accessButtons.Clear();
AccessLevelGrid.DisposeAllChildren();
foreach (var access in accessLevels)
{
if (!prototypeManager.TryIndex(access, out var accessLevel))
if (!protoManager.TryIndex(access, out var accessLevel))
{
logMill.Error($"Unable to find accesslevel for {access}");
continue;
}
@@ -44,11 +42,16 @@ namespace Content.Client.Access.UI
AccessLevelGrid.AddChild(newButton);
_accessButtons.Add(accessLevel.ID, newButton);
newButton.OnPressed += _ => SubmitData();
newButton.OnPressed += _ =>
{
OnSubmit?.Invoke(
// Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair
_accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId<AccessLevelPrototype>(x.Key)).ToList());
};
}
}
public void UpdateState(AccessOverriderBoundUserInterfaceState state)
public void UpdateState(IPrototypeManager protoManager, AccessOverriderBoundUserInterfaceState state)
{
PrivilegedIdLabel.Text = state.PrivilegedIdName;
PrivilegedIdButton.Text = state.IsPrivilegedIdPresent
@@ -66,11 +69,11 @@ namespace Content.Client.Access.UI
if (state.MissingPrivilegesList != null && state.MissingPrivilegesList.Any())
{
List<string> missingPrivileges = new List<string>();
var missingPrivileges = new List<string>();
foreach (string tag in state.MissingPrivilegesList)
{
string privilege = Loc.GetString(_prototypeManager.Index<AccessLevelPrototype>(tag)?.Name ?? "generic-unknown");
var privilege = Loc.GetString(protoManager.Index<AccessLevelPrototype>(tag)?.Name ?? "generic-unknown");
missingPrivileges.Add(privilege);
}
@@ -90,13 +93,5 @@ namespace Content.Client.Access.UI
}
}
}
private void SubmitData()
{
_owner.SubmitData(
// Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair
_accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId<AccessLevelPrototype>(x.Key)).ToList());
}
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Access.Systems;
using Content.Shared.StatusIcon;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Shared.Prototypes;
namespace Content.Client.Access.UI
@@ -20,16 +21,11 @@ namespace Content.Client.Access.UI
{
base.Open();
_window?.Dispose();
_window = new AgentIDCardWindow(this);
if (State != null)
UpdateState(State);
_window = this.CreateWindow<AgentIDCardWindow>();
_window.OpenCentered();
_window.OnClose += Close;
_window.OnNameChanged += OnNameChanged;
_window.OnJobChanged += OnJobChanged;
_window.OnJobIconChanged += OnJobIconChanged;
}
private void OnNameChanged(string newName)
@@ -61,14 +57,5 @@ namespace Content.Client.Access.UI
_window.SetCurrentJob(cast.CurrentJob);
_window.SetAllowedIcons(cast.Icons, cast.CurrentJobIconId);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_window?.Dispose();
}
}
}

View File

@@ -17,19 +17,19 @@ namespace Content.Client.Access.UI
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
private readonly SpriteSystem _spriteSystem;
private readonly AgentIDCardBoundUserInterface _bui;
private const int JobIconColumnCount = 10;
public event Action<string>? OnNameChanged;
public event Action<string>? OnJobChanged;
public AgentIDCardWindow(AgentIDCardBoundUserInterface bui)
public event Action<ProtoId<StatusIconPrototype>>? OnJobIconChanged;
public AgentIDCardWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_spriteSystem = _entitySystem.GetEntitySystem<SpriteSystem>();
_bui = bui;
NameLineEdit.OnTextEntered += e => OnNameChanged?.Invoke(e.Text);
NameLineEdit.OnFocusExit += e => OnNameChanged?.Invoke(e.Text);
@@ -67,7 +67,7 @@ namespace Content.Client.Access.UI
};
// Generate buttons textures
TextureRect jobIconTexture = new TextureRect
var jobIconTexture = new TextureRect
{
Texture = _spriteSystem.Frame0(jobIcon.Icon),
TextureScale = new Vector2(2.5f, 2.5f),
@@ -75,7 +75,7 @@ namespace Content.Client.Access.UI
};
jobIconButton.AddChild(jobIconTexture);
jobIconButton.OnPressed += _ => _bui.OnJobIconChanged(jobIconId);
jobIconButton.OnPressed += _ => OnJobIconChanged?.Invoke(jobIcon.ID);
IconGrid.AddChild(jobIconButton);
if (jobIconId.Equals(currentJobIconId))

View File

@@ -107,7 +107,7 @@ namespace Content.Client.Actions
UpdateAction(uid, component);
}
protected override void UpdateAction(EntityUid? actionId, BaseActionComponent? action = null)
public override void UpdateAction(EntityUid? actionId, BaseActionComponent? action = null)
{
if (!ResolveActionData(actionId, ref action))
return;

View File

@@ -14,7 +14,6 @@ namespace Content.Client.Administration.UI.Tabs.ObjectsTab;
public sealed partial class ObjectsTab : Control
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
private readonly Color _altColor = Color.FromHex("#292B38");
private readonly Color _defaultColor = Color.FromHex("#2F2F3B");

View File

@@ -1,5 +1,6 @@
using Content.Shared.Ame.Components;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
namespace Content.Client.Ame.UI
{
@@ -16,9 +17,8 @@ namespace Content.Client.Ame.UI
{
base.Open();
_window = new AmeWindow(this);
_window.OnClose += Close;
_window.OpenCentered();
_window = this.CreateWindow<AmeWindow>();
_window.OnAmeButton += ButtonPressed;
}
/// <summary>
@@ -40,15 +40,5 @@ namespace Content.Client.Ame.UI
{
SendMessage(new UiButtonPressedMessage(button));
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_window?.Dispose();
}
}
}
}

View File

@@ -1,3 +1,4 @@
using System.Linq;
using Content.Client.UserInterface;
using Content.Shared.Ame.Components;
using Robust.Client.AutoGenerated;
@@ -9,15 +10,17 @@ namespace Content.Client.Ame.UI
[GenerateTypedNameReferences]
public sealed partial class AmeWindow : DefaultWindow
{
public AmeWindow(AmeControllerBoundUserInterface ui)
public event Action<UiButton>? OnAmeButton;
public AmeWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
EjectButton.OnPressed += _ => ui.ButtonPressed(UiButton.Eject);
ToggleInjection.OnPressed += _ => ui.ButtonPressed(UiButton.ToggleInjection);
IncreaseFuelButton.OnPressed += _ => ui.ButtonPressed(UiButton.IncreaseFuel);
DecreaseFuelButton.OnPressed += _ => ui.ButtonPressed(UiButton.DecreaseFuel);
EjectButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.Eject);
ToggleInjection.OnPressed += _ => OnAmeButton?.Invoke(UiButton.ToggleInjection);
IncreaseFuelButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.IncreaseFuel);
DecreaseFuelButton.OnPressed += _ => OnAmeButton?.Invoke(UiButton.DecreaseFuel);
}
/// <summary>
@@ -29,7 +32,7 @@ namespace Content.Client.Ame.UI
var castState = (AmeControllerBoundUserInterfaceState) state;
// Disable all buttons if not powered
if (Contents.Children != null)
if (Contents.Children.Any())
{
ButtonHelpers.SetButtonDisabledRecursive(Contents, !castState.HasPower);
EjectButton.Disabled = false;
@@ -65,8 +68,8 @@ namespace Content.Client.Ame.UI
CoreCount.Text = $"{castState.CoreCount}";
InjectionAmount.Text = $"{castState.InjectionAmount}";
// format power statistics to pretty numbers
CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply.ToString("N1")}";
TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply.ToString("N1")}";
CurrentPowerSupply.Text = $"{castState.CurrentPowerSupply:N1}";
TargetedPowerSupply.Text = $"{castState.TargetedPowerSupply:N1}";
}
}
}

View File

@@ -2,6 +2,7 @@ using Content.Shared.Anomaly;
using Content.Shared.Gravity;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Anomaly.Ui;
@@ -18,10 +19,8 @@ public sealed class AnomalyGeneratorBoundUserInterface : BoundUserInterface
{
base.Open();
_window = new(Owner);
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<AnomalyGeneratorWindow>();
_window.SetEntity(Owner);
_window.OnGenerateButtonPressed += () =>
{
@@ -37,18 +36,5 @@ public sealed class AnomalyGeneratorBoundUserInterface : BoundUserInterface
return;
_window?.UpdateState(msg);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
public void SetPowerSwitch(bool on)
{
SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on));
}
}

View File

@@ -18,17 +18,21 @@ public sealed partial class AnomalyGeneratorWindow : FancyWindow
public Action? OnGenerateButtonPressed;
public AnomalyGeneratorWindow(EntityUid gen)
public AnomalyGeneratorWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
EntityView.SetEntity(gen);
EntityView.SpriteOffset = false;
GenerateButton.OnPressed += _ => OnGenerateButtonPressed?.Invoke();
}
public void SetEntity(EntityUid uid)
{
EntityView.SetEntity(uid);
}
public void UpdateState(AnomalyGeneratorUserInterfaceState state)
{
_cooldownEnd = state.CooldownEndTime;

View File

@@ -28,8 +28,6 @@ namespace Content.Client.Arcade
private static readonly Vector2 BlockSize = new(15, 15);
private readonly BlockGameBoundUserInterface _owner;
private readonly PanelContainer _mainPanel;
private readonly BoxContainer _gameRootContainer;
@@ -58,10 +56,11 @@ namespace Content.Client.Arcade
private bool _isPlayer = false;
private bool _gameOver = false;
public BlockGameMenu(BlockGameBoundUserInterface owner)
public event Action<BlockGamePlayerAction>? OnAction;
public BlockGameMenu()
{
Title = Loc.GetString("blockgame-menu-title");
_owner = owner;
MinSize = SetSize = new Vector2(410, 490);
@@ -176,7 +175,7 @@ namespace Content.Client.Arcade
};
_newGameButton.OnPressed += (e) =>
{
_owner.SendAction(BlockGamePlayerAction.NewGame);
OnAction?.Invoke(BlockGamePlayerAction.NewGame);
};
pauseMenuContainer.AddChild(_newGameButton);
pauseMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
@@ -186,7 +185,10 @@ namespace Content.Client.Arcade
Text = Loc.GetString("blockgame-menu-button-scoreboard"),
TextAlign = Label.AlignMode.Center
};
_scoreBoardButton.OnPressed += (e) => _owner.SendAction(BlockGamePlayerAction.ShowHighscores);
_scoreBoardButton.OnPressed += (e) =>
{
OnAction?.Invoke(BlockGamePlayerAction.ShowHighscores);
};
pauseMenuContainer.AddChild(_scoreBoardButton);
_unpauseButtonMargin = new Control { MinSize = new Vector2(1, 10), Visible = false };
pauseMenuContainer.AddChild(_unpauseButtonMargin);
@@ -199,7 +201,7 @@ namespace Content.Client.Arcade
};
_unpauseButton.OnPressed += (e) =>
{
_owner.SendAction(BlockGamePlayerAction.Unpause);
OnAction?.Invoke(BlockGamePlayerAction.Unpause);
};
pauseMenuContainer.AddChild(_unpauseButton);
@@ -257,7 +259,7 @@ namespace Content.Client.Arcade
};
_finalNewGameButton.OnPressed += (e) =>
{
_owner.SendAction(BlockGamePlayerAction.NewGame);
OnAction?.Invoke(BlockGamePlayerAction.NewGame);
};
gameOverMenuContainer.AddChild(_finalNewGameButton);
@@ -327,7 +329,10 @@ namespace Content.Client.Arcade
Text = Loc.GetString("blockgame-menu-button-back"),
TextAlign = Label.AlignMode.Center
};
_highscoreBackButton.OnPressed += (e) => _owner.SendAction(BlockGamePlayerAction.Pause);
_highscoreBackButton.OnPressed += (e) =>
{
OnAction?.Invoke(BlockGamePlayerAction.Pause);
};
menuContainer.AddChild(_highscoreBackButton);
menuInnerPanel.AddChild(menuContainer);
@@ -375,7 +380,7 @@ namespace Content.Client.Arcade
{
PanelOverride = back,
HorizontalExpand = true,
SizeFlagsStretchRatio = 60
SizeFlagsStretchRatio = 34.25f
};
var backgroundPanel = new PanelContainer
{
@@ -473,7 +478,7 @@ namespace Content.Client.Arcade
private void TryPause()
{
_owner.SendAction(BlockGamePlayerAction.Pause);
OnAction?.Invoke(BlockGamePlayerAction.Pause);
}
public void SetStarted()
@@ -576,19 +581,19 @@ namespace Content.Client.Arcade
return;
else if (args.Function == ContentKeyFunctions.ArcadeLeft)
_owner.SendAction(BlockGamePlayerAction.StartLeft);
OnAction?.Invoke(BlockGamePlayerAction.StartLeft);
else if (args.Function == ContentKeyFunctions.ArcadeRight)
_owner.SendAction(BlockGamePlayerAction.StartRight);
OnAction?.Invoke(BlockGamePlayerAction.StartRight);
else if (args.Function == ContentKeyFunctions.ArcadeUp)
_owner.SendAction(BlockGamePlayerAction.Rotate);
OnAction?.Invoke(BlockGamePlayerAction.Rotate);
else if (args.Function == ContentKeyFunctions.Arcade3)
_owner.SendAction(BlockGamePlayerAction.CounterRotate);
OnAction?.Invoke(BlockGamePlayerAction.CounterRotate);
else if (args.Function == ContentKeyFunctions.ArcadeDown)
_owner.SendAction(BlockGamePlayerAction.SoftdropStart);
OnAction?.Invoke(BlockGamePlayerAction.SoftdropStart);
else if (args.Function == ContentKeyFunctions.Arcade2)
_owner.SendAction(BlockGamePlayerAction.Hold);
OnAction?.Invoke(BlockGamePlayerAction.Hold);
else if (args.Function == ContentKeyFunctions.Arcade1)
_owner.SendAction(BlockGamePlayerAction.Harddrop);
OnAction?.Invoke(BlockGamePlayerAction.Harddrop);
}
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
@@ -599,11 +604,11 @@ namespace Content.Client.Arcade
return;
else if (args.Function == ContentKeyFunctions.ArcadeLeft)
_owner.SendAction(BlockGamePlayerAction.EndLeft);
OnAction?.Invoke(BlockGamePlayerAction.EndLeft);
else if (args.Function == ContentKeyFunctions.ArcadeRight)
_owner.SendAction(BlockGamePlayerAction.EndRight);
OnAction?.Invoke(BlockGamePlayerAction.EndRight);
else if (args.Function == ContentKeyFunctions.ArcadeDown)
_owner.SendAction(BlockGamePlayerAction.SoftdropEnd);
OnAction?.Invoke(BlockGamePlayerAction.SoftdropEnd);
}
public void UpdateNextBlock(BlockGameBlock[] blocks)

View File

@@ -8,8 +8,6 @@ namespace Content.Client.Arcade
{
public sealed class SpaceVillainArcadeMenu : DefaultWindow
{
public SpaceVillainArcadeBoundUserInterface Owner { get; set; }
private readonly Label _enemyNameLabel;
private readonly Label _playerInfoLabel;
private readonly Label _enemyInfoLabel;
@@ -17,11 +15,13 @@ namespace Content.Client.Arcade
private readonly Label _enemyActionLabel;
private readonly Button[] _gameButtons = new Button[3]; //used to disable/enable all game buttons
public SpaceVillainArcadeMenu(SpaceVillainArcadeBoundUserInterface owner)
public event Action<SharedSpaceVillainArcadeComponent.PlayerAction>? OnPlayerAction;
public SpaceVillainArcadeMenu()
{
MinSize = SetSize = new Vector2(300, 225);
Title = Loc.GetString("spacevillain-menu-title");
Owner = owner;
var grid = new GridContainer { Columns = 1 };
@@ -47,32 +47,43 @@ namespace Content.Client.Arcade
grid.AddChild(_enemyActionLabel);
var buttonGrid = new GridContainer { Columns = 3 };
_gameButtons[0] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Attack)
_gameButtons[0] = new Button()
{
Text = Loc.GetString("spacevillain-menu-button-attack")
};
_gameButtons[0].OnPressed +=
_ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Attack);
buttonGrid.AddChild(_gameButtons[0]);
_gameButtons[1] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Heal)
_gameButtons[1] = new Button()
{
Text = Loc.GetString("spacevillain-menu-button-heal")
};
_gameButtons[1].OnPressed +=
_ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Heal);
buttonGrid.AddChild(_gameButtons[1]);
_gameButtons[2] = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.Recharge)
_gameButtons[2] = new Button()
{
Text = Loc.GetString("spacevillain-menu-button-recharge")
};
_gameButtons[2].OnPressed +=
_ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.Recharge);
buttonGrid.AddChild(_gameButtons[2]);
centerContainer = new CenterContainer();
centerContainer.AddChild(buttonGrid);
grid.AddChild(centerContainer);
var newGame = new ActionButton(Owner, SharedSpaceVillainArcadeComponent.PlayerAction.NewGame)
var newGame = new Button()
{
Text = Loc.GetString("spacevillain-menu-button-new-game")
};
newGame.OnPressed += _ => OnPlayerAction?.Invoke(SharedSpaceVillainArcadeComponent.PlayerAction.NewGame);
grid.AddChild(newGame);
Contents.AddChild(grid);
@@ -99,23 +110,5 @@ namespace Content.Client.Arcade
_playerActionLabel.Text = message.PlayerActionMessage;
_enemyActionLabel.Text = message.EnemyActionMessage;
}
private sealed class ActionButton : Button
{
private readonly SpaceVillainArcadeBoundUserInterface _owner;
private readonly SharedSpaceVillainArcadeComponent.PlayerAction _playerAction;
public ActionButton(SpaceVillainArcadeBoundUserInterface owner, SharedSpaceVillainArcadeComponent.PlayerAction playerAction)
{
_owner = owner;
_playerAction = playerAction;
OnPressed += Clicked;
}
private void Clicked(ButtonEventArgs e)
{
_owner.SendAction(_playerAction);
}
}
}
}

View File

@@ -1,5 +1,6 @@
using Content.Shared.Arcade;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Arcade.UI;
@@ -15,9 +16,8 @@ public sealed class BlockGameBoundUserInterface : BoundUserInterface
{
base.Open();
_menu = new BlockGameMenu(this);
_menu.OnClose += Close;
_menu.OpenCentered();
_menu = this.CreateWindow<BlockGameMenu>();
_menu.OnAction += SendAction;
}
protected override void ReceiveMessage(BoundUserInterfaceMessage message)

View File

@@ -1,4 +1,5 @@
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Shared.GameObjects;
using Robust.Shared.ViewVariables;
using static Content.Shared.Arcade.SharedSpaceVillainArcadeComponent;
@@ -9,8 +10,6 @@ public sealed class SpaceVillainArcadeBoundUserInterface : BoundUserInterface
{
[ViewVariables] private SpaceVillainArcadeMenu? _menu;
//public SharedSpaceVillainArcadeComponent SpaceVillainArcade;
public SpaceVillainArcadeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
SendAction(PlayerAction.RequestData);
@@ -25,10 +24,8 @@ public sealed class SpaceVillainArcadeBoundUserInterface : BoundUserInterface
{
base.Open();
_menu = new SpaceVillainArcadeMenu(this);
_menu.OnClose += Close;
_menu.OpenCentered();
_menu = this.CreateWindow<SpaceVillainArcadeMenu>();
_menu.OnPlayerAction += SendAction;
}
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
@@ -36,12 +33,4 @@ public sealed class SpaceVillainArcadeBoundUserInterface : BoundUserInterface
if (message is SpaceVillainArcadeDataUpdateMessage msg)
_menu?.UpdateInfo(msg);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
_menu?.Dispose();
}
}

View File

@@ -2,6 +2,7 @@ using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Monitor.Components;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
@@ -20,16 +21,9 @@ public sealed class AirAlarmBoundUserInterface : BoundUserInterface
{
base.Open();
_window = new AirAlarmWindow(this);
_window = this.CreateWindow<AirAlarmWindow>();
_window.SetEntity(Owner);
if (State != null)
{
UpdateState(State);
}
_window.OpenCentered();
_window.OnClose += Close;
_window.AtmosDeviceDataChanged += OnDeviceDataChanged;
_window.AtmosDeviceDataCopied += OnDeviceDataCopied;
_window.AtmosAlarmThresholdChanged += OnThresholdChanged;

View File

@@ -47,7 +47,7 @@ public sealed partial class AirAlarmWindow : FancyWindow
private CheckBox _autoMode => AutoModeCheckBox;
public AirAlarmWindow(BoundUserInterface owner)
public AirAlarmWindow()
{
RobustXamlLoader.Load(this);
@@ -95,8 +95,11 @@ public sealed partial class AirAlarmWindow : FancyWindow
_sensors.Clear();
ResyncAllRequested!.Invoke();
};
}
EntityView.SetEntity(owner.Owner);
public void SetEntity(EntityUid uid)
{
EntityView.SetEntity(uid);
}
public void UpdateState(AirAlarmUIState state)

View File

@@ -1,6 +1,7 @@
using Content.Shared.Atmos.Piping.Binary.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Atmos.UI
{
@@ -21,14 +22,8 @@ namespace Content.Client.Atmos.UI
{
base.Open();
_window = new GasCanisterWindow();
_window = this.CreateWindow<GasCanisterWindow>();
if (State != null)
UpdateState(State);
_window.OpenCentered();
_window.OnClose += Close;
_window.ReleaseValveCloseButtonPressed += OnReleaseValveClosePressed;
_window.ReleaseValveOpenButtonPressed += OnReleaseValveOpenPressed;
_window.ReleasePressureSet += OnReleasePressureSet;

View File

@@ -3,6 +3,7 @@ using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping.Trinary.Components;
using Content.Shared.Localizations;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
namespace Content.Client.Atmos.UI
{
@@ -28,14 +29,8 @@ namespace Content.Client.Atmos.UI
var atmosSystem = EntMan.System<AtmosphereSystem>();
_window = new GasFilterWindow(atmosSystem.Gases);
if (State != null)
UpdateState(State);
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<GasFilterWindow>();
_window.PopulateGasList(atmosSystem.Gases);
_window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed;
_window.FilterTransferRateChanged += OnFilterTransferRatePressed;

View File

@@ -26,10 +26,9 @@ namespace Content.Client.Atmos.UI
public event Action<string>? FilterTransferRateChanged;
public event Action? SelectGasPressed;
public GasFilterWindow(IEnumerable<GasPrototype> gases)
public GasFilterWindow()
{
RobustXamlLoader.Load(this);
PopulateGasList(gases);
ToggleStatusButton.OnPressed += _ => SetFilterStatus(!FilterStatus);
ToggleStatusButton.OnPressed += _ => ToggleStatusButtonPressed?.Invoke();
@@ -73,7 +72,7 @@ namespace Content.Client.Atmos.UI
SelectGasButton.Disabled = true;
}
private void PopulateGasList(IEnumerable<GasPrototype> gases)
public void PopulateGasList(IEnumerable<GasPrototype> gases)
{
GasList.Add(new ItemList.Item(GasList)
{
@@ -81,7 +80,7 @@ namespace Content.Client.Atmos.UI
Text = Loc.GetString("comp-gas-filter-ui-filter-gas-none")
});
foreach (GasPrototype gas in gases)
foreach (var gas in gases)
{
var gasName = Loc.GetString(gas.Name);
GasList.Add(GetGasItem(gas.ID, gasName, GasList));

View File

@@ -2,7 +2,7 @@ using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping.Trinary.Components;
using Content.Shared.Localizations;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Atmos.UI
{
@@ -26,14 +26,7 @@ namespace Content.Client.Atmos.UI
{
base.Open();
_window = new GasMixerWindow();
if (State != null)
UpdateState(State);
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<GasMixerWindow>();
_window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed;
_window.MixerOutputPressureChanged += OnMixerOutputPressurePressed;
@@ -83,12 +76,5 @@ namespace Content.Client.Atmos.UI
_window.SetOutputPressure(cast.OutputPressure);
_window.SetNodePercentages(cast.NodeOne);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
}
}

View File

@@ -3,6 +3,7 @@ using Content.Shared.Atmos.Piping.Binary.Components;
using Content.Shared.Localizations;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Atmos.UI
{
@@ -26,14 +27,7 @@ namespace Content.Client.Atmos.UI
{
base.Open();
_window = new GasPressurePumpWindow();
if (State != null)
UpdateState(State);
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<GasPressurePumpWindow>();
_window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed;
_window.PumpOutputPressureChanged += OnPumpOutputPressurePressed;
@@ -67,12 +61,5 @@ namespace Content.Client.Atmos.UI
_window.SetPumpStatus(cast.Enabled);
_window.SetOutputPressure(cast.OutputPressure);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
}
}

View File

@@ -2,6 +2,7 @@
using Content.Shared.Atmos.Piping.Unary.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Atmos.UI
{
@@ -31,14 +32,7 @@ namespace Content.Client.Atmos.UI
{
base.Open();
_window = new GasThermomachineWindow();
if (State != null)
UpdateState(State);
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<GasThermomachineWindow>();
_window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed();
_window.TemperatureSpinbox.OnValueChanged += _ => OnTemperatureChanged(_window.TemperatureSpinbox.Value);
@@ -91,12 +85,5 @@ namespace Content.Client.Atmos.UI
true => Loc.GetString("comp-gas-thermomachine-ui-title-heater")
};
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
}
}

View File

@@ -3,6 +3,7 @@ using Content.Shared.Atmos.Piping.Binary.Components;
using Content.Shared.Localizations;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Atmos.UI
{
@@ -26,14 +27,7 @@ namespace Content.Client.Atmos.UI
{
base.Open();
_window = new GasVolumePumpWindow();
if (State != null)
UpdateState(State);
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<GasVolumePumpWindow>();
_window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed;
_window.PumpTransferRateChanged += OnPumpTransferRatePressed;
@@ -64,16 +58,9 @@ namespace Content.Client.Atmos.UI
if (_window == null || state is not GasVolumePumpBoundUserInterfaceState cast)
return;
_window.Title = (cast.PumpLabel);
_window.Title = cast.PumpLabel;
_window.SetPumpStatus(cast.Enabled);
_window.SetTransferRate(cast.TransferRate);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
}
}

View File

@@ -1,5 +1,6 @@
using Content.Shared.Atmos.Piping.Portable.Components;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
namespace Content.Client.Atmos.UI;
@@ -21,14 +22,7 @@ public sealed class SpaceHeaterBoundUserInterface : BoundUserInterface
{
base.Open();
_window = new SpaceHeaterWindow();
if (State != null)
UpdateState(State);
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<SpaceHeaterWindow>();
_window.ToggleStatusButton.OnPressed += _ => OnToggleStatusButtonPressed();
_window.IncreaseTempRange.OnPressed += _ => OnTemperatureRangeChanged(_window.TemperatureChangeDelta);

View File

@@ -1,8 +1,7 @@
using Content.Shared.Audio.Jukebox;
using Robust.Client.Audio;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Shared.Audio.Components;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
namespace Content.Client.Audio.Jukebox;
@@ -23,9 +22,7 @@ public sealed class JukeboxBoundUserInterface : BoundUserInterface
{
base.Open();
_menu = new JukeboxMenu();
_menu.OnClose += Close;
_menu.OpenCentered();
_menu = this.CreateWindow<JukeboxMenu>();
_menu.OnPlayPressed += args =>
{
@@ -100,19 +97,5 @@ public sealed class JukeboxBoundUserInterface : BoundUserInterface
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

@@ -1,5 +1,6 @@
using Content.Shared.Bed.Cryostorage;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
namespace Content.Client.Bed.Cryostorage;
@@ -17,9 +18,7 @@ public sealed class CryostorageBoundUserInterface : BoundUserInterface
{
base.Open();
_menu = new();
_menu.OnClose += Close;
_menu = this.CreateWindow<CryostorageMenu>();
_menu.SlotRemoveButtonPressed += (ent, slot) =>
{
@@ -30,8 +29,6 @@ public sealed class CryostorageBoundUserInterface : BoundUserInterface
{
SendMessage(new CryostorageRemoveItemBuiMessage(ent, hand, CryostorageRemoveItemBuiMessage.RemovalType.Hand));
};
_menu.OpenCentered();
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -45,12 +42,4 @@ public sealed class CryostorageBoundUserInterface : BoundUserInterface
break;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Dispose();
}
}

View File

@@ -1,6 +1,7 @@
using Content.Client.Cargo.UI;
using Content.Shared.Cargo.Components;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
namespace Content.Client.Cargo.BUI;
@@ -18,9 +19,7 @@ public sealed class CargoBountyConsoleBoundUserInterface : BoundUserInterface
{
base.Open();
_menu = new();
_menu.OnClose += Close;
_menu = this.CreateWindow<CargoBountyMenu>();
_menu.OnLabelButtonPressed += id =>
{
@@ -31,8 +30,6 @@ public sealed class CargoBountyConsoleBoundUserInterface : BoundUserInterface
{
SendMessage(new BountySkipMessage(id));
};
_menu.OpenCentered();
}
protected override void UpdateState(BoundUserInterfaceState message)
@@ -44,14 +41,4 @@ public sealed class CargoBountyConsoleBoundUserInterface : BoundUserInterface
_menu?.UpdateEntries(state.Bounties, state.UntilNextSkip);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Dispose();
}
}

View File

@@ -2,6 +2,7 @@ using Content.Client.Cargo.UI;
using Content.Shared.Cargo.BUI;
using Content.Shared.Cargo.Events;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Cargo.BUI;
@@ -18,21 +19,9 @@ public sealed class CargoPalletConsoleBoundUserInterface : BoundUserInterface
{
base.Open();
_menu = new CargoPalletMenu();
_menu = this.CreateWindow<CargoPalletMenu>();
_menu.AppraiseRequested += OnAppraisal;
_menu.SellRequested += OnSell;
_menu.OnClose += Close;
_menu.OpenCentered();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_menu?.Dispose();
}
}
private void OnAppraisal()

View File

@@ -2,6 +2,7 @@ using Content.Client.Cargo.UI;
using Content.Shared.Cargo.BUI;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Shared.Prototypes;
namespace Content.Client.Cargo.BUI;
@@ -9,6 +10,8 @@ namespace Content.Client.Cargo.BUI;
[UsedImplicitly]
public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[ViewVariables]
private CargoShuttleMenu? _menu;
@@ -19,24 +22,7 @@ public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface
protected override void Open()
{
base.Open();
var collection = IoCManager.Instance;
if (collection == null)
return;
_menu = new CargoShuttleMenu(collection.Resolve<IPrototypeManager>(), collection.Resolve<IEntitySystemManager>().GetEntitySystem<SpriteSystem>());
_menu.OnClose += Close;
_menu.OpenCentered();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_menu?.Dispose();
}
_menu = this.CreateWindow<CargoShuttleMenu>();
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -45,6 +31,6 @@ public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface
if (state is not CargoShuttleConsoleBoundUserInterfaceState cargoState) return;
_menu?.SetAccountName(cargoState.AccountName);
_menu?.SetShuttleName(cargoState.ShuttleName);
_menu?.SetOrders(cargoState.Orders);
_menu?.SetOrders(EntMan.System<SpriteSystem>(), _protoManager, cargoState.Orders);
}
}

View File

@@ -12,14 +12,9 @@ namespace Content.Client.Cargo.UI
[GenerateTypedNameReferences]
public sealed partial class CargoShuttleMenu : FancyWindow
{
private readonly IPrototypeManager _protoManager;
private readonly SpriteSystem _spriteSystem;
public CargoShuttleMenu(IPrototypeManager protoManager, SpriteSystem spriteSystem)
public CargoShuttleMenu()
{
RobustXamlLoader.Load(this);
_protoManager = protoManager;
_spriteSystem = spriteSystem;
Title = Loc.GetString("cargo-shuttle-console-menu-title");
}
@@ -33,19 +28,19 @@ namespace Content.Client.Cargo.UI
ShuttleNameLabel.Text = name;
}
public void SetOrders(List<CargoOrderData> orders)
public void SetOrders(SpriteSystem sprites, IPrototypeManager protoManager, List<CargoOrderData> orders)
{
Orders.DisposeAllChildren();
foreach (var order in orders)
{
var product = _protoManager.Index<EntityPrototype>(order.ProductId);
var product = protoManager.Index<EntityPrototype>(order.ProductId);
var productName = product.Name;
var row = new CargoOrderRow
{
Order = order,
Icon = { Texture = _spriteSystem.Frame0(product) },
Icon = { Texture = sprites.Frame0(product) },
ProductName =
{
Text = Loc.GetString(

View File

@@ -31,7 +31,7 @@ public sealed partial class NewsReaderUiFragment : BoxContainer
Author.Visible = true;
PageName.Text = article.Title;
PageText.SetMarkup(article.Content);
PageText.SetMarkupPermissive(article.Content);
PageNum.Text = $"{targetNum}/{totalNum}";

View File

@@ -2,6 +2,7 @@ using Content.Shared.Chemistry;
using Content.Shared.Containers.ItemSlots;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Chemistry.UI
{
@@ -27,13 +28,8 @@ namespace Content.Client.Chemistry.UI
base.Open();
// Setup window layout/elements
_window = new ChemMasterWindow
{
Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName,
};
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<ChemMasterWindow>();
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
// Setup static button actions.
_window.InputEjectButton.OnPressed += _ => SendMessage(
@@ -75,15 +71,5 @@ namespace Content.Client.Chemistry.UI
_window?.UpdateState(castState); // Update window state
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_window?.Dispose();
}
}
}
}

View File

@@ -3,6 +3,7 @@ using Content.Shared.Chemistry;
using Content.Shared.Containers.ItemSlots;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Chemistry.UI
{
@@ -15,9 +16,6 @@ namespace Content.Client.Chemistry.UI
[ViewVariables]
private ReagentDispenserWindow? _window;
[ViewVariables]
private ReagentDispenserBoundUserInterfaceState? _lastState;
public ReagentDispenserBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
@@ -32,14 +30,9 @@ namespace Content.Client.Chemistry.UI
base.Open();
// Setup window layout/elements
_window = new()
{
Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName,
HelpGuidebookIds = EntMan.GetComponent<GuideHelpComponent>(Owner).Guides
};
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<ReagentDispenserWindow>();
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
_window.HelpGuidebookIds = EntMan.GetComponent<GuideHelpComponent>(Owner).Guides;
// Setup static button actions.
_window.EjectButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(SharedReagentDispenser.OutputSlotName));
@@ -63,19 +56,7 @@ namespace Content.Client.Chemistry.UI
base.UpdateState(state);
var castState = (ReagentDispenserBoundUserInterfaceState) state;
_lastState = castState;
_window?.UpdateState(castState); //Update window state
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_window?.Dispose();
}
}
}
}

View File

@@ -2,6 +2,7 @@ using Content.Shared.Chemistry;
using Content.Shared.FixedPoint;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Chemistry.UI
{
@@ -18,7 +19,7 @@ namespace Content.Client.Chemistry.UI
protected override void Open()
{
base.Open();
_window = new TransferAmountWindow();
_window = this.CreateWindow<TransferAmountWindow>();
_window.ApplyButton.OnPressed += _ =>
{
@@ -28,15 +29,6 @@ namespace Content.Client.Chemistry.UI
_window.Close();
}
};
_window.OnClose += Close;
_window.OpenCentered();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
}
}

View File

@@ -1,6 +1,7 @@
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Content.Shared.Cloning.CloningConsole;
using Robust.Client.UserInterface;
namespace Content.Client.CloningConsole.UI
{
@@ -17,13 +18,11 @@ namespace Content.Client.CloningConsole.UI
protected override void Open()
{
base.Open();
_window = new CloningConsoleWindow
{
Title = Loc.GetString("cloning-console-window-title")
};
_window.OnClose += Close;
_window = this.CreateWindow<CloningConsoleWindow>();
_window.Title = Loc.GetString("cloning-console-window-title");
_window.CloneButton.OnPressed += _ => SendMessage(new UiButtonPressedMessage(UiButton.Clone));
_window.OpenCentered();
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -32,19 +31,5 @@ namespace Content.Client.CloningConsole.UI
_window?.Populate((CloningConsoleBoundUserInterfaceState) state);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
if (_window != null)
{
_window.OnClose -= Close;
_window.CloneButton.OnPressed -= _ => SendMessage(new UiButtonPressedMessage(UiButton.Clone));
}
_window?.Dispose();
}
}
}

View File

@@ -1,10 +1,12 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Numerics;
using Content.Client.DisplacementMap;
using Content.Client.Inventory;
using Content.Shared.Clothing;
using Content.Shared.Clothing.Components;
using Content.Shared.Clothing.EntitySystems;
using Content.Shared.DisplacementMap;
using Content.Shared.Humanoid;
using Content.Shared.Inventory;
using Content.Shared.Inventory.Events;
@@ -57,6 +59,7 @@ public sealed class ClientClothingSystem : ClothingSystem
[Dependency] private readonly IResourceCache _cache = default!;
[Dependency] private readonly ISerializationManager _serialization = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!;
[Dependency] private readonly DisplacementMapSystem _displacement = default!;
public override void Initialize()
{
@@ -71,15 +74,14 @@ public sealed class ClientClothingSystem : ClothingSystem
private void OnAppearanceUpdate(EntityUid uid, InventoryComponent component, ref AppearanceChangeEvent args)
{
// May need to update jumpsuit stencils if the sex changed. Also required to properly set the stencil on init
// May need to update displacement maps if the sex changed. Also required to properly set the stencil on init
if (args.Sprite == null)
return;
if (_inventorySystem.TryGetSlotEntity(uid, Jumpsuit, out var suit, component)
&& TryComp(suit, out ClothingComponent? clothing))
var enumerator = _inventorySystem.GetSlotEnumerator((uid, component));
while (enumerator.NextItem(out var item, out var slot))
{
SetGenderedMask(uid, args.Sprite, clothing);
return;
RenderEquipment(uid, item, slot.Name, component);
}
// No clothing equipped -> make sure the layer is hidden, though this should already be handled by on-unequip.
@@ -186,14 +188,6 @@ public sealed class ClientClothingSystem : ClothingSystem
private void OnDidUnequip(EntityUid uid, SpriteComponent component, DidUnequipEvent args)
{
// Hide jumpsuit mask layer.
if (args.Slot == Jumpsuit
&& TryComp(uid, out SpriteComponent? sprite)
&& sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var maskLayer))
{
sprite.LayerSetVisible(maskLayer, false);
}
if (!TryComp(uid, out InventorySlotsComponent? inventorySlots))
return;
@@ -238,9 +232,6 @@ public sealed class ClientClothingSystem : ClothingSystem
return;
}
if (slot == Jumpsuit)
SetGenderedMask(equipee, sprite, clothingComponent);
if (!_inventorySystem.TryGetSlot(equipee, slot, out var slotDef, inventory))
return;
@@ -272,7 +263,25 @@ 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);
// Select displacement maps
var displacementData = inventory.Displacements.GetValueOrDefault(slot); //Default unsexed map
var equipeeSex = CompOrNull<HumanoidAppearanceComponent>(equipee)?.Sex;
if (equipeeSex != null)
{
switch (equipeeSex)
{
case Sex.Male:
if (inventory.MaleDisplacements.Count > 0)
displacementData = inventory.MaleDisplacements.GetValueOrDefault(slot);
break;
case Sex.Female:
if (inventory.FemaleDisplacements.Count > 0)
displacementData = inventory.FemaleDisplacements.GetValueOrDefault(slot);
break;
}
}
// add the new layers
foreach (var (key, layerData) in ev.Layers)
@@ -299,7 +308,7 @@ public sealed class ClientClothingSystem : ClothingSystem
index = sprite.LayerMapReserveBlank(key);
if (sprite[index] is not Layer layer)
return;
continue;
// In case no RSI is given, use the item's base RSI as a default. This cuts down on a lot of unnecessary yaml entries.
if (layerData.RsiPath == null
@@ -310,90 +319,19 @@ public sealed class ClientClothingSystem : ClothingSystem
layer.SetRsi(clothingSprite.BaseRSI);
}
// Another "temporary" fix for clothing stencil masks.
// Sprite layer redactor when
// Sprite "redactor" just a week away.
if (slot == Jumpsuit)
layerData.Shader ??= "StencilDraw";
sprite.LayerSetData(index, layerData);
layer.Offset += slotDef.Offset;
if (displacementData != null)
if (displacementData is not 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}.");
//Checking that the state is not tied to the current race. In this case we don't need to use the displacement maps.
if (layerData.State is not null && inventory.SpeciesId is not null && layerData.State.EndsWith(inventory.SpeciesId))
continue;
}
//CP14 48*48 displacement maps support
var displacementDataLayer = displacementData.Layer;
var actualRSI = sprite.LayerGetActualRSI(index);
if (actualRSI != null)
{
var layerSize = actualRSI.Size;
if (layerSize.X == 48 && displacementData.Layer48 != null)
displacementDataLayer = displacementData.Layer48;
}
var displacementLayer = _serialization.CreateCopy(displacementDataLayer, notNullableOverride: true);
//CP14 48*48 displacement maps support end
displacementLayer.CopyToShaderParameters!.LayerKey = key;
// Add before main layer for this item.
sprite.AddLayer(displacementLayer, index);
sprite.LayerMapSet(displacementKey, index);
revealedLayers.Add(displacementKey);
_displacement.TryAddDisplacement(displacementData, sprite, index, key, revealedLayers);
}
}
RaiseLocalEvent(equipment, new EquipmentVisualsUpdatedEvent(equipee, slot, revealedLayers), true);
}
/// <summary>
/// Sets a sprite's gendered mask based on gender (obviously).
/// </summary>
/// <param name="sprite">Sprite to modify</param>
/// <param name="humanoid">Humanoid, to get gender from</param>
/// <param name="clothing">Clothing component, to get mask sprite type</param>
private void SetGenderedMask(EntityUid uid, SpriteComponent sprite, ClothingComponent clothing)
{
if (!sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var layer))
return;
ClothingMask mask;
string prefix;
switch (CompOrNull<HumanoidAppearanceComponent>(uid)?.Sex)
{
case Sex.Male:
mask = clothing.MaleMask;
prefix = "male_";
break;
case Sex.Female:
mask = clothing.FemaleMask;
prefix = "female_";
break;
default:
mask = clothing.UnisexMask;
prefix = "unisex_";
break;
}
sprite.LayerSetState(layer, mask switch
{
ClothingMask.NoMask => $"{prefix}none",
ClothingMask.UniformTop => $"{prefix}top",
_ => $"{prefix}full",
});
sprite.LayerSetVisible(layer, true);
}
}

View File

@@ -2,6 +2,7 @@
using Content.Shared.Clothing.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Clothing.UI;
@@ -22,10 +23,8 @@ public sealed class ChameleonBoundUserInterface : BoundUserInterface
{
base.Open();
_menu = new ChameleonMenu();
_menu.OnClose += Close;
_menu = this.CreateWindow<ChameleonMenu>();
_menu.OnIdSelected += OnIdSelected;
_menu.OpenCentered();
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -42,15 +41,4 @@ public sealed class ChameleonBoundUserInterface : BoundUserInterface
{
SendMessage(new ChameleonPrototypeSelectedMessage(selectedId));
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_menu?.Close();
_menu = null;
}
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Communications;
using Robust.Client.UserInterface;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
@@ -8,34 +9,11 @@ namespace Content.Client.Communications.UI
{
public sealed class CommunicationsConsoleBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[ViewVariables]
private CommunicationsConsoleMenu? _menu;
[ViewVariables]
public bool CanAnnounce { get; private set; }
[ViewVariables]
public bool CanBroadcast { get; private set; }
[ViewVariables]
public bool CanCall { get; private set; }
[ViewVariables]
public bool CountdownStarted { get; private set; }
[ViewVariables]
public bool AlertLevelSelectable { get; private set; }
[ViewVariables]
public string CurrentLevel { get; private set; } = default!;
[ViewVariables]
private TimeSpan? _expectedCountdownTime;
public int Countdown => _expectedCountdownTime == null ? 0 : Math.Max((int) _expectedCountdownTime.Value.Subtract(_gameTiming.CurTime).TotalSeconds, 0);
public CommunicationsConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
@@ -44,23 +22,25 @@ namespace Content.Client.Communications.UI
{
base.Open();
_menu = new CommunicationsConsoleMenu(this);
_menu.OnClose += Close;
_menu.OpenCentered();
_menu = this.CreateWindow<CommunicationsConsoleMenu>();
_menu.OnAnnounce += AnnounceButtonPressed;
_menu.OnBroadcast += BroadcastButtonPressed;
_menu.OnAlertLevel += AlertLevelSelected;
_menu.OnEmergencyLevel += EmergencyShuttleButtonPressed;
}
public void AlertLevelSelected(string level)
{
if (AlertLevelSelectable)
if (_menu!.AlertLevelSelectable)
{
CurrentLevel = level;
_menu.CurrentLevel = level;
SendMessage(new CommunicationsConsoleSelectAlertLevelMessage(level));
}
}
public void EmergencyShuttleButtonPressed()
{
if (CountdownStarted)
if (_menu!.CountdownStarted)
RecallShuttle();
else
CallShuttle();
@@ -95,31 +75,23 @@ namespace Content.Client.Communications.UI
if (state is not CommunicationsConsoleInterfaceState commsState)
return;
CanAnnounce = commsState.CanAnnounce;
CanBroadcast = commsState.CanBroadcast;
CanCall = commsState.CanCall;
_expectedCountdownTime = commsState.ExpectedCountdownEnd;
CountdownStarted = commsState.CountdownStarted;
AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0;
CurrentLevel = commsState.CurrentAlert;
if (_menu != null)
{
_menu.CanAnnounce = commsState.CanAnnounce;
_menu.CanBroadcast = commsState.CanBroadcast;
_menu.CanCall = commsState.CanCall;
_menu.CountdownStarted = commsState.CountdownStarted;
_menu.AlertLevelSelectable = commsState.AlertLevels != null && !float.IsNaN(commsState.CurrentAlertDelay) && commsState.CurrentAlertDelay <= 0;
_menu.CurrentLevel = commsState.CurrentAlert;
_menu.CountdownEnd = commsState.ExpectedCountdownEnd;
_menu.UpdateCountdown();
_menu.UpdateAlertLevels(commsState.AlertLevels, CurrentLevel);
_menu.AlertLevelButton.Disabled = !AlertLevelSelectable;
_menu.EmergencyShuttleButton.Disabled = !CanCall;
_menu.AnnounceButton.Disabled = !CanAnnounce;
_menu.BroadcastButton.Disabled = !CanBroadcast;
_menu.UpdateAlertLevels(commsState.AlertLevels, _menu.CurrentLevel);
_menu.AlertLevelButton.Disabled = !_menu.AlertLevelSelectable;
_menu.EmergencyShuttleButton.Disabled = !_menu.CanCall;
_menu.AnnounceButton.Disabled = !_menu.CanAnnounce;
_menu.BroadcastButton.Disabled = !_menu.CanBroadcast;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_menu?.Dispose();
}
}
}

View File

@@ -1,31 +1,40 @@
using Content.Client.UserInterface.Controls;
using System.Threading;
using System.Globalization;
using Content.Client.UserInterface.Controls;
using Content.Shared.CCVar;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Timer = Robust.Shared.Timing.Timer;
namespace Content.Client.Communications.UI
{
[GenerateTypedNameReferences]
public sealed partial class CommunicationsConsoleMenu : FancyWindow
{
private CommunicationsConsoleBoundUserInterface Owner { get; set; }
private readonly CancellationTokenSource _timerCancelTokenSource = new();
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly ILocalizationManager _loc = default!;
public CommunicationsConsoleMenu(CommunicationsConsoleBoundUserInterface owner)
public bool CanAnnounce;
public bool CanBroadcast;
public bool CanCall;
public bool AlertLevelSelectable;
public bool CountdownStarted;
public string CurrentLevel = string.Empty;
public TimeSpan? CountdownEnd;
public event Action? OnEmergencyLevel;
public event Action<string>? OnAlertLevel;
public event Action<string>? OnAnnounce;
public event Action<string>? OnBroadcast;
public CommunicationsConsoleMenu()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
Owner = owner;
var loc = IoCManager.Resolve<ILocalizationManager>();
MessageInput.Placeholder = new Rope.Leaf(loc.GetString("comms-console-menu-announcement-placeholder"));
MessageInput.Placeholder = new Rope.Leaf(_loc.GetString("comms-console-menu-announcement-placeholder"));
var maxAnnounceLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength);
MessageInput.OnTextChanged += (args) =>
@@ -37,33 +46,38 @@ namespace Content.Client.Communications.UI
}
else
{
AnnounceButton.Disabled = !owner.CanAnnounce;
AnnounceButton.Disabled = !CanAnnounce;
AnnounceButton.ToolTip = null;
}
};
AnnounceButton.OnPressed += (_) => Owner.AnnounceButtonPressed(Rope.Collapse(MessageInput.TextRope));
AnnounceButton.Disabled = !owner.CanAnnounce;
AnnounceButton.OnPressed += _ => OnAnnounce?.Invoke(Rope.Collapse(MessageInput.TextRope));
AnnounceButton.Disabled = !CanAnnounce;
BroadcastButton.OnPressed += (_) => Owner.BroadcastButtonPressed(Rope.Collapse(MessageInput.TextRope));
BroadcastButton.Disabled = !owner.CanBroadcast;
BroadcastButton.OnPressed += _ => OnBroadcast?.Invoke(Rope.Collapse(MessageInput.TextRope));
BroadcastButton.Disabled = !CanBroadcast;
AlertLevelButton.OnItemSelected += args =>
{
var metadata = AlertLevelButton.GetItemMetadata(args.Id);
if (metadata != null && metadata is string cast)
{
Owner.AlertLevelSelected(cast);
OnAlertLevel?.Invoke(cast);
}
};
AlertLevelButton.Disabled = !owner.AlertLevelSelectable;
EmergencyShuttleButton.OnPressed += (_) => Owner.EmergencyShuttleButtonPressed();
EmergencyShuttleButton.Disabled = !owner.CanCall;
AlertLevelButton.Disabled = !AlertLevelSelectable;
EmergencyShuttleButton.OnPressed += _ => OnEmergencyLevel?.Invoke();
EmergencyShuttleButton.Disabled = !CanCall;
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
UpdateCountdown();
Timer.SpawnRepeating(1000, UpdateCountdown, _timerCancelTokenSource.Token);
}
// The current alert could make levels unselectable, so we need to ensure that the UI reacts properly.
@@ -105,32 +119,19 @@ namespace Content.Client.Communications.UI
public void UpdateCountdown()
{
if (!Owner.CountdownStarted)
if (!CountdownStarted)
{
CountdownLabel.SetMessage("");
CountdownLabel.SetMessage(string.Empty);
EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-call-shuttle");
return;
}
var diff = MathHelper.Max((CountdownEnd - _timing.CurTime) ?? TimeSpan.Zero, TimeSpan.Zero);
EmergencyShuttleButton.Text = Loc.GetString("comms-console-menu-recall-shuttle");
var infoText = Loc.GetString($"comms-console-menu-time-remaining",
("time", Owner.Countdown.ToString()));
("time", diff.TotalSeconds.ToString(CultureInfo.CurrentCulture)));
CountdownLabel.SetMessage(infoText);
}
public override void Close()
{
base.Close();
_timerCancelTokenSource.Cancel();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
_timerCancelTokenSource.Cancel();
}
}
}

View File

@@ -1,4 +1,5 @@
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.CustomControls;
namespace Content.Client.Computer
@@ -19,10 +20,8 @@ namespace Content.Client.Computer
{
base.Open();
_window = (TWindow) _dynamicTypeFactory.CreateInstance(typeof(TWindow));
_window = this.CreateWindow<TWindow>();
_window.SetupComputerWindow(this);
_window.OnClose += Close;
_window.OpenCentered();
}
// Alas, this constructor has to be copied to the subclass. :(
@@ -42,16 +41,6 @@ namespace Content.Client.Computer
_window.UpdateState((TState) state);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_window?.Dispose();
}
}
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
_window?.ReceiveMessage(message);

View File

@@ -1,5 +1,6 @@
using System.Text.RegularExpressions;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using static Content.Shared.Configurable.ConfigurationComponent;
namespace Content.Client.Configurable.UI
@@ -9,9 +10,6 @@ namespace Content.Client.Configurable.UI
[ViewVariables]
private ConfigurationMenu? _menu;
[ViewVariables]
public Regex? Validation { get; internal set; }
public ConfigurationBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
@@ -19,10 +17,8 @@ namespace Content.Client.Configurable.UI
protected override void Open()
{
base.Open();
_menu = new ConfigurationMenu(this);
_menu.OnClose += Close;
_menu.OpenCentered();
_menu = this.CreateWindow<ConfigurationMenu>();
_menu.OnConfiguration += SendConfiguration;
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -30,9 +26,7 @@ namespace Content.Client.Configurable.UI
base.UpdateState(state);
if (state is not ConfigurationBoundUserInterfaceState configurationState)
{
return;
}
_menu?.Populate(configurationState);
}
@@ -41,9 +35,12 @@ namespace Content.Client.Configurable.UI
{
base.ReceiveMessage(message);
if (_menu == null)
return;
if (message is ValidationUpdateMessage msg)
{
Validation = new Regex(msg.ValidationString, RegexOptions.Compiled);
_menu.Validation = new Regex(msg.ValidationString, RegexOptions.Compiled);
}
}
@@ -51,16 +48,5 @@ namespace Content.Client.Configurable.UI
{
SendMessage(new ConfigurationUpdatedMessage(config));
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing && _menu != null)
{
_menu.OnClose -= Close;
_menu.Close();
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Numerics;
using System.Text.RegularExpressions;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
@@ -13,23 +14,25 @@ namespace Content.Client.Configurable.UI
{
public sealed class ConfigurationMenu : DefaultWindow
{
public ConfigurationBoundUserInterface Owner { get; }
private readonly BoxContainer _column;
private readonly BoxContainer _row;
private readonly List<(string name, LineEdit input)> _inputs;
public ConfigurationMenu(ConfigurationBoundUserInterface owner)
[ViewVariables]
public Regex? Validation { get; internal set; }
public event Action<Dictionary<string, string>>? OnConfiguration;
public ConfigurationMenu()
{
MinSize = SetSize = new Vector2(300, 250);
Owner = owner;
_inputs = new List<(string name, LineEdit input)>();
Title = Loc.GetString("configuration-menu-device-title");
BoxContainer baseContainer = new BoxContainer
var baseContainer = new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
VerticalExpand = true,
@@ -116,14 +119,13 @@ namespace Content.Client.Configurable.UI
private void OnConfirm(ButtonEventArgs args)
{
var config = GenerateDictionary(_inputs, "Text");
Owner.SendConfiguration(config);
OnConfiguration?.Invoke(config);
Close();
}
private bool Validate(string value)
{
return Owner.Validation == null || Owner.Validation.IsMatch(value);
return Validation?.IsMatch(value) != false;
}
private Dictionary<string, string> GenerateDictionary(IEnumerable<(string name, LineEdit input)> inputs, string propertyName)

View File

@@ -26,7 +26,6 @@ namespace Content.Client.Construction
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly ExamineSystemShared _examineSystem = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;

View File

@@ -1,5 +1,6 @@
using Content.Shared.Construction.Components;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
namespace Content.Client.Construction.UI
{
@@ -17,8 +18,8 @@ namespace Content.Client.Construction.UI
{
base.Open();
_menu = new FlatpackCreatorMenu(Owner);
_menu.OnClose += Close;
_menu = this.CreateWindow<FlatpackCreatorMenu>();
_menu.SetEntity(Owner);
_menu.PackButtonPressed += () =>
{
@@ -27,14 +28,5 @@ namespace Content.Client.Construction.UI
_menu.OpenCentered();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Dispose();
}
}
}

View File

@@ -24,7 +24,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow
private readonly FlatpackSystem _flatpack;
private readonly MaterialStorageSystem _materialStorage;
private readonly EntityUid _owner;
private EntityUid _owner;
[ValidatePrototypeId<EntityPrototype>]
public const string NoBoardEffectId = "FlatpackerNoBoardEffect";
@@ -33,7 +33,7 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow
public event Action? PackButtonPressed;
public FlatpackCreatorMenu(EntityUid uid)
public FlatpackCreatorMenu()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
@@ -42,14 +42,17 @@ public sealed partial class FlatpackCreatorMenu : FancyWindow
_flatpack = _entityManager.System<FlatpackSystem>();
_materialStorage = _entityManager.System<MaterialStorageSystem>();
_owner = uid;
PackButton.OnPressed += _ => PackButtonPressed?.Invoke();
MaterialStorageControl.SetOwner(uid);
InsertLabel.SetMarkup(Loc.GetString("flatpacker-ui-insert-board"));
}
public void SetEntity(EntityUid uid)
{
_owner = uid;
MaterialStorageControl.SetOwner(uid);
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);

View File

@@ -2,12 +2,15 @@
using Content.Shared.Crayon;
using Content.Shared.Decals;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Shared.Prototypes;
namespace Content.Client.Crayon.UI
{
public sealed class CrayonBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[ViewVariables]
private CrayonWindow? _menu;
@@ -18,15 +21,29 @@ namespace Content.Client.Crayon.UI
protected override void Open()
{
base.Open();
_menu = new CrayonWindow(this);
_menu.OnClose += Close;
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
var crayonDecals = prototypeManager.EnumeratePrototypes<DecalPrototype>().Where(x => x.Tags.Contains("crayon"));
_menu.Populate(crayonDecals);
_menu = this.CreateWindow<CrayonWindow>();
_menu.OnColorSelected += SelectColor;
_menu.OnSelected += Select;
PopulateCrayons();
_menu.OpenCenteredLeft();
}
private void PopulateCrayons()
{
var crayonDecals = _protoManager.EnumeratePrototypes<DecalPrototype>().Where(x => x.Tags.Contains("crayon"));
_menu?.Populate(crayonDecals);
}
public override void OnProtoReload(PrototypesReloadedEventArgs args)
{
base.OnProtoReload(args);
if (!args.WasModified<DecalPrototype>())
return;
PopulateCrayons();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
@@ -43,16 +60,5 @@ namespace Content.Client.Crayon.UI
{
SendMessage(new CrayonColorMessage(color));
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_menu?.Close();
_menu = null;
}
}
}
}

View File

@@ -18,18 +18,17 @@ namespace Content.Client.Crayon.UI
[GenerateTypedNameReferences]
public sealed partial class CrayonWindow : DefaultWindow
{
public CrayonBoundUserInterface Owner { get; }
private Dictionary<string, Texture>? _decals;
private string? _selected;
private Color _color;
public CrayonWindow(CrayonBoundUserInterface owner)
public event Action<Color>? OnColorSelected;
public event Action<string>? OnSelected;
public CrayonWindow()
{
RobustXamlLoader.Load(this);
Owner = owner;
Search.OnTextChanged += _ => RefreshList();
ColorSelector.OnColorChanged += SelectColor;
}
@@ -38,16 +37,16 @@ namespace Content.Client.Crayon.UI
{
_color = color;
Owner.SelectColor(color);
OnColorSelected?.Invoke(color);
RefreshList();
}
private void RefreshList()
{
// Clear
Grid.RemoveAllChildren();
if (_decals == null) return;
Grid.DisposeAllChildren();
if (_decals == null)
return;
var filter = Search.Text;
foreach (var (decal, tex) in _decals)
@@ -89,8 +88,8 @@ namespace Content.Client.Crayon.UI
{
if (obj.Button.Name == null) return;
Owner.Select(obj.Button.Name);
_selected = obj.Button.Name;
OnSelected?.Invoke(_selected);
RefreshList();
}

View File

@@ -0,0 +1,65 @@
using Content.Shared.DisplacementMap;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.Serialization.Manager;
namespace Content.Client.DisplacementMap;
public sealed class DisplacementMapSystem : EntitySystem
{
[Dependency] private readonly ISerializationManager _serialization = default!;
public bool TryAddDisplacement(DisplacementData data, SpriteComponent sprite, int index, string key, HashSet<string> revealedLayers)
{
if (data.ShaderOverride != null)
sprite.LayerSetShader(index, data.ShaderOverride);
var displacementKey = $"{key}-displacement";
if (!revealedLayers.Add(displacementKey))
{
Log.Warning($"Duplicate key for DISPLACEMENT: {displacementKey}.");
return false;
}
//allows you not to write it every time in the YML
foreach (var pair in data.SizeMaps)
{
pair.Value.CopyToShaderParameters??= new()
{
LayerKey = "dummy",
ParameterTexture = "displacementMap",
ParameterUV = "displacementUV",
};
}
if (!data.SizeMaps.ContainsKey(32))
{
Log.Error($"DISPLACEMENT: {displacementKey} don't have 32x32 default displacement map");
return false;
}
// We choose a displacement map from the possible ones, matching the size with the original layer size.
// If there is no such a map, we use a standard 32 by 32 one
var displacementDataLayer = data.SizeMaps[EyeManager.PixelsPerMeter];
var actualRSI = sprite.LayerGetActualRSI(index);
if (actualRSI is not null)
{
if (actualRSI.Size.X != actualRSI.Size.Y)
Log.Warning($"DISPLACEMENT: {displacementKey} has a resolution that is not 1:1, things can look crooked");
var layerSize = actualRSI.Size.X;
if (data.SizeMaps.ContainsKey(layerSize))
displacementDataLayer = data.SizeMaps[layerSize];
}
var displacementLayer = _serialization.CreateCopy(displacementDataLayer, notNullableOverride: true);
displacementLayer.CopyToShaderParameters!.LayerKey = key;
sprite.AddLayer(displacementLayer, index);
sprite.LayerMapSet(displacementKey, index);
revealedLayers.Add(displacementKey);
return true;
}
}

View File

@@ -1,5 +1,6 @@
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using static Content.Shared.Disposal.Components.SharedDisposalRouterComponent;
namespace Content.Client.Disposal.UI
@@ -21,20 +22,16 @@ namespace Content.Client.Disposal.UI
{
base.Open();
_window = new DisposalRouterWindow();
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<DisposalRouterWindow>();
_window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text);
_window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text);
}
private void ButtonPressed(UiAction action, string tag)
{
SendMessage(new UiActionMessage(action, tag));
_window?.Close();
Close();
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -48,18 +45,5 @@ namespace Content.Client.Disposal.UI
_window?.UpdateState(cast);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_window?.Dispose();
}
}
}
}

View File

@@ -1,5 +1,6 @@
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using static Content.Shared.Disposal.Components.SharedDisposalTaggerComponent;
namespace Content.Client.Disposal.UI
@@ -21,20 +22,17 @@ namespace Content.Client.Disposal.UI
{
base.Open();
_window = new DisposalTaggerWindow();
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<DisposalTaggerWindow>();
_window.Confirm.OnPressed += _ => ButtonPressed(UiAction.Ok, _window.TagInput.Text);
_window.TagInput.OnTextEntered += args => ButtonPressed(UiAction.Ok, args.Text);
}
private void ButtonPressed(UiAction action, string tag)
{
// TODO: This looks copy-pasted with the other mailing stuff...
SendMessage(new UiActionMessage(action, tag));
_window?.Close();
Close();
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -48,18 +46,5 @@ namespace Content.Client.Disposal.UI
_window?.UpdateState(cast);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_window?.Dispose();
}
}
}
}

View File

@@ -2,6 +2,7 @@ using Content.Shared.Disposal;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;
namespace Content.Client.Disposal.UI
{
@@ -11,6 +12,8 @@ namespace Content.Client.Disposal.UI
[GenerateTypedNameReferences]
public sealed partial class MailingUnitWindow : DefaultWindow
{
public TimeSpan FullPressure;
public MailingUnitWindow()
{
RobustXamlLoader.Load(this);
@@ -26,6 +29,7 @@ namespace Content.Client.Disposal.UI
Title = Loc.GetString("ui-mailing-unit-window-title", ("tag", state.Tag ?? " "));
UnitState.Text = disposalState.UnitState;
FullPressure = disposalState.FullPressureTime;
var pressureReached = PressureBar.UpdatePressure(disposalState.FullPressureTime);
Power.Pressed = disposalState.Powered;
Engage.Pressed = disposalState.Engaged;
@@ -42,9 +46,10 @@ namespace Content.Client.Disposal.UI
return !disposalState.Powered || pressureReached;
}
public bool UpdatePressure(TimeSpan stateFullPressureTime)
protected override void FrameUpdate(FrameEventArgs args)
{
return PressureBar.UpdatePressure(stateFullPressureTime);
base.FrameUpdate(args);
PressureBar.UpdatePressure(FullPressure);
}
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Access;
using Content.Shared.Doors.Electronics;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Shared.Prototypes;
namespace Content.Client.Doors.Electronics;
@@ -18,6 +19,23 @@ public sealed class DoorElectronicsBoundUserInterface : BoundUserInterface
protected override void Open()
{
base.Open();
_window = this.CreateWindow<DoorElectronicsConfigurationMenu>();
_window.OnAccessChanged += UpdateConfiguration;
Reset();
}
public override void OnProtoReload(PrototypesReloadedEventArgs args)
{
base.OnProtoReload(args);
if (!args.WasModified<AccessLevelPrototype>())
return;
Reset();
}
private void Reset()
{
List<ProtoId<AccessLevelPrototype>> accessLevels = new();
foreach (var accessLevel in _prototypeManager.EnumeratePrototypes<AccessLevelPrototype>())
@@ -29,10 +47,7 @@ public sealed class DoorElectronicsBoundUserInterface : BoundUserInterface
}
accessLevels.Sort();
_window = new DoorElectronicsConfigurationMenu(this, accessLevels, _prototypeManager);
_window.OnClose += Close;
_window.OpenCentered();
_window?.Reset(_prototypeManager, accessLevels);
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -44,14 +59,6 @@ public sealed class DoorElectronicsBoundUserInterface : BoundUserInterface
_window?.UpdateState(castState);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
public void UpdateConfiguration(List<ProtoId<AccessLevelPrototype>> newAccessList)
{
SendMessage(new DoorElectronicsUpdateConfigurationMessage(newAccessList));

View File

@@ -15,22 +15,23 @@ namespace Content.Client.Doors.Electronics;
[GenerateTypedNameReferences]
public sealed partial class DoorElectronicsConfigurationMenu : FancyWindow
{
private readonly DoorElectronicsBoundUserInterface _owner;
private AccessLevelControl _buttonsList = new();
private readonly AccessLevelControl _buttonsList = new();
public DoorElectronicsConfigurationMenu(DoorElectronicsBoundUserInterface ui, List<ProtoId<AccessLevelPrototype>> accessLevels, IPrototypeManager prototypeManager)
public event Action<List<ProtoId<AccessLevelPrototype>>>? OnAccessChanged;
public DoorElectronicsConfigurationMenu()
{
RobustXamlLoader.Load(this);
_owner = ui;
_buttonsList.Populate(accessLevels, prototypeManager);
AccessLevelControlContainer.AddChild(_buttonsList);
}
foreach (var (id, button) in _buttonsList.ButtonsList)
public void Reset(IPrototypeManager protoManager, List<ProtoId<AccessLevelPrototype>> accessLevels)
{
_buttonsList.Populate(accessLevels, protoManager);
foreach (var button in _buttonsList.ButtonsList.Values)
{
button.OnPressed += _ => _owner.UpdateConfiguration(
_buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList());
button.OnPressed += _ => OnAccessChanged?.Invoke(_buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList());
}
}

View File

@@ -25,24 +25,30 @@ public sealed class FaxVisualsSystem : EntitySystem
if (args.Sprite == null)
return;
if (_appearance.TryGetData(uid, FaxMachineVisuals.VisualState, out FaxMachineVisualState visuals) && visuals == FaxMachineVisualState.Inserting)
if (_player.HasRunningAnimation(uid, "faxecute"))
return;
if (_appearance.TryGetData(uid, FaxMachineVisuals.VisualState, out FaxMachineVisualState visuals) &&
visuals == FaxMachineVisualState.Inserting)
{
_player.Play(uid, new Animation()
{
Length = TimeSpan.FromSeconds(2.4),
AnimationTracks =
_player.Play(uid,
new Animation()
{
new AnimationTrackSpriteFlick()
Length = TimeSpan.FromSeconds(2.4),
AnimationTracks =
{
LayerKey = FaxMachineVisuals.VisualState,
KeyFrames =
new AnimationTrackSpriteFlick()
{
new AnimationTrackSpriteFlick.KeyFrame(component.InsertingState, 0f),
new AnimationTrackSpriteFlick.KeyFrame("icon", 2.4f),
}
}
}
}, "faxecute");
LayerKey = FaxMachineVisuals.VisualState,
KeyFrames =
{
new AnimationTrackSpriteFlick.KeyFrame(component.InsertingState, 0f),
new AnimationTrackSpriteFlick.KeyFrame("icon", 2.4f),
},
},
},
},
"faxecute");
}
}
}

View File

@@ -25,10 +25,7 @@ public sealed class FaxBoundUi : BoundUserInterface
{
base.Open();
_window = new FaxWindow();
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<FaxWindow>();
_window.FileButtonPressed += OnFileButtonPressed;
_window.CopyButtonPressed += OnCopyButtonPressed;
_window.SendButtonPressed += OnSendButtonPressed;
@@ -104,11 +101,4 @@ public sealed class FaxBoundUi : BoundUserInterface
_window.UpdateState(cast);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
_window?.Dispose();
}
}

View File

@@ -1,6 +1,7 @@
using Robust.Client.GameObjects;
using Robust.Shared.Timing;
using Content.Shared.Forensics;
using Robust.Client.UserInterface;
namespace Content.Client.Forensics
{
@@ -21,11 +22,9 @@ namespace Content.Client.Forensics
protected override void Open()
{
base.Open();
_window = new ForensicScannerMenu();
_window.OnClose += Close;
_window = this.CreateWindow<ForensicScannerMenu>();
_window.Print.OnPressed += _ => Print();
_window.Clear.OnPressed += _ => Clear();
_window.OpenCentered();
}
private void Print()
@@ -62,6 +61,7 @@ namespace Content.Client.Forensics
_printCooldown = cast.PrintCooldown;
// TODO: Fix this
if (cast.PrintReadyAt > _gameTiming.CurTime)
Timer.Spawn(cast.PrintReadyAt - _gameTiming.CurTime, () =>
{
@@ -71,14 +71,5 @@ namespace Content.Client.Forensics
_window.UpdateState(cast);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_window?.Dispose();
}
}
}

View File

@@ -185,7 +185,7 @@ namespace Content.Client.Gameplay
EntityCoordinates coordinates = default;
EntityUid? entityToClick = null;
if (args.Viewport is IViewportControl vp)
if (args.Viewport is IViewportControl vp && kArgs.PointerLocation.IsValid)
{
var mousePosWorld = vp.PixelToMap(kArgs.PointerLocation.Position);
entityToClick = GetClickedEntity(mousePosWorld);
@@ -194,6 +194,10 @@ namespace Content.Client.Gameplay
grid.MapToGrid(mousePosWorld) :
EntityCoordinates.FromMap(_mapManager, mousePosWorld);
}
else
{
coordinates = EntityCoordinates.Invalid;
}
var message = new ClientFullInputCmdMessage(_timing.CurTick, _timing.TickFraction, funcId)
{

View File

@@ -1,6 +1,7 @@
using Content.Shared.Gateway;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Gateway.UI;
@@ -17,24 +18,13 @@ public sealed class GatewayBoundUserInterface : BoundUserInterface
{
base.Open();
_window = new GatewayWindow(EntMan.GetNetEntity(Owner));
_window = this.CreateWindow<GatewayWindow>();
_window.SetEntity(EntMan.GetNetEntity(Owner));
_window.OpenPortal += destination =>
{
SendMessage(new GatewayOpenPortalMessage(destination));
};
_window.OnClose += Close;
_window?.OpenCentered();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_window?.Dispose();
_window = null;
}
}
protected override void UpdateState(BoundUserInterfaceState state)

View File

@@ -22,7 +22,7 @@ public sealed partial class GatewayWindow : FancyWindow,
public event Action<NetEntity>? OpenPortal;
private List<GatewayDestinationData> _destinations = new();
public readonly NetEntity Owner;
public NetEntity Owner;
private NetEntity? _current;
private TimeSpan _nextReady;
@@ -46,16 +46,20 @@ public sealed partial class GatewayWindow : FancyWindow,
/// </summary>
private bool _isCooldownPending = true;
public GatewayWindow(NetEntity netEntity)
public GatewayWindow()
{
RobustXamlLoader.Load(this);
var dependencies = IoCManager.Instance!;
_timing = dependencies.Resolve<IGameTiming>();
Owner = netEntity;
NextUnlockBar.ForegroundStyleBoxOverride = new StyleBoxFlat(Color.FromHex("#C74EBD"));
}
public void SetEntity(NetEntity entity)
{
}
public void UpdateState(GatewayBoundUserInterfaceState state)
{
_destinations = state.Destinations;

View File

@@ -0,0 +1,29 @@
using Content.Shared.Ghost.Roles;
using Robust.Client.UserInterface;
using Robust.Shared.Prototypes;
namespace Content.Client.Ghost;
public sealed class GhostRoleRadioBoundUserInterface : BoundUserInterface
{
private GhostRoleRadioMenu? _ghostRoleRadioMenu;
public GhostRoleRadioBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
protected override void Open()
{
base.Open();
_ghostRoleRadioMenu = this.CreateWindow<GhostRoleRadioMenu>();
_ghostRoleRadioMenu.SetEntity(Owner);
_ghostRoleRadioMenu.SendGhostRoleRadioMessageAction += SendGhostRoleRadioMessage;
}
public void SendGhostRoleRadioMessage(ProtoId<GhostRolePrototype> protoId)
{
SendMessage(new GhostRoleRadioMessage(protoId));
}
}

View File

@@ -0,0 +1,8 @@
<ui:RadialMenu
xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls"
CloseButtonStyleClass="RadialMenuCloseButton"
VerticalExpand="True"
HorizontalExpand="True">
<ui:RadialContainer Name="Main">
</ui:RadialContainer>
</ui:RadialMenu>

View File

@@ -0,0 +1,107 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.Ghost.Roles;
using Content.Shared.Ghost.Roles.Components;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using System.Numerics;
namespace Content.Client.Ghost;
public sealed partial class GhostRoleRadioMenu : RadialMenu
{
[Dependency] private readonly EntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public event Action<ProtoId<GhostRolePrototype>>? SendGhostRoleRadioMessageAction;
public EntityUid Entity { get; set; }
public GhostRoleRadioMenu()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
}
public void SetEntity(EntityUid uid)
{
Entity = uid;
RefreshUI();
}
private void RefreshUI()
{
// The main control that will contain all of the clickable options
var main = FindControl<RadialContainer>("Main");
// The purpose of this radial UI is for ghost role radios that allow you to select
// more than one potential option, such as with kobolds/lizards.
// This means that it won't show anything if SelectablePrototypes is empty.
if (!_entityManager.TryGetComponent<GhostRoleMobSpawnerComponent>(Entity, out var comp))
return;
foreach (var ghostRoleProtoString in comp.SelectablePrototypes)
{
// For each prototype we find we want to create a button that uses the name of the ghost role
// as the hover tooltip, and the icon is taken from either the ghost role entityprototype
// or the indicated icon entityprototype.
if (!_prototypeManager.TryIndex<GhostRolePrototype>(ghostRoleProtoString, out var ghostRoleProto))
continue;
var button = new GhostRoleRadioMenuButton()
{
StyleClasses = { "RadialMenuButton" },
SetSize = new Vector2(64, 64),
ToolTip = Loc.GetString(ghostRoleProto.Name),
ProtoId = ghostRoleProto.ID,
};
var entProtoView = new EntityPrototypeView()
{
SetSize = new Vector2(48, 48),
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center,
Stretch = SpriteView.StretchMode.Fill
};
// pick the icon if it exists, otherwise fallback to the ghost role's entity
if (_prototypeManager.TryIndex(ghostRoleProto.IconPrototype, out var iconProto))
entProtoView.SetPrototype(iconProto);
else
entProtoView.SetPrototype(comp.Prototype);
button.AddChild(entProtoView);
main.AddChild(button);
AddGhostRoleRadioMenuButtonOnClickActions(main);
}
}
private void AddGhostRoleRadioMenuButtonOnClickActions(Control control)
{
var mainControl = control as RadialContainer;
if (mainControl == null)
return;
foreach (var child in mainControl.Children)
{
var castChild = child as GhostRoleRadioMenuButton;
if (castChild == null)
continue;
castChild.OnButtonUp += _ =>
{
SendGhostRoleRadioMessageAction?.Invoke(castChild.ProtoId);
Close();
};
}
}
}
public sealed class GhostRoleRadioMenuButton : RadialMenuTextureButton
{
public ProtoId<GhostRolePrototype> ProtoId { get; set; }
}

View File

@@ -1,6 +1,6 @@
using Content.Shared.Gravity;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Gravity.UI
{
@@ -18,17 +18,8 @@ namespace Content.Client.Gravity.UI
{
base.Open();
_window = new GravityGeneratorWindow(this);
/*
_window.Switch.OnPressed += _ =>
{
SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(!IsOn));
};
*/
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<GravityGeneratorWindow>();
_window.SetEntity(Owner);
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -39,14 +30,6 @@ namespace Content.Client.Gravity.UI
_window?.UpdateState(castState);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
public void SetPowerSwitch(bool on)
{
SendMessage(new SharedGravityGeneratorComponent.SwitchGeneratorMessage(on));

View File

@@ -12,22 +12,23 @@ namespace Content.Client.Gravity.UI
{
private readonly ButtonGroup _buttonGroup = new();
private readonly GravityGeneratorBoundUserInterface _owner;
public event Action<bool>? OnPowerSwitch;
public GravityGeneratorWindow(GravityGeneratorBoundUserInterface owner)
public GravityGeneratorWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_owner = owner;
OnButton.Group = _buttonGroup;
OffButton.Group = _buttonGroup;
OnButton.OnPressed += _ => _owner.SetPowerSwitch(true);
OffButton.OnPressed += _ => _owner.SetPowerSwitch(false);
OnButton.OnPressed += _ => OnPowerSwitch?.Invoke(true);
OffButton.OnPressed += _ => OnPowerSwitch?.Invoke(false);
}
EntityView.SetEntity(owner.Owner);
public void SetEntity(EntityUid uid)
{
EntityView.SetEntity(uid);
}
public void UpdateState(SharedGravityGeneratorComponent.GeneratorState state)

View File

@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Client.DisplacementMap;
using Content.Client.Examine;
using Content.Client.Strip;
using Content.Client.Verbs.UI;
@@ -15,7 +16,6 @@ using Robust.Client.UserInterface;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Player;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Timing;
namespace Content.Client.Hands.Systems
@@ -29,7 +29,7 @@ namespace Content.Client.Hands.Systems
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly StrippableSystem _stripSys = default!;
[Dependency] private readonly ExamineSystem _examine = default!;
[Dependency] private readonly ISerializationManager _serialization = default!; //CP14
[Dependency] private readonly DisplacementMapSystem _displacement = default!;
public event Action<string, HandLocation>? OnPlayerAddHand;
public event Action<string>? OnPlayerRemoveHand;
@@ -324,8 +324,6 @@ namespace Content.Client.Hands.Systems
return;
}
var displacementData = handComp.Displacements.GetValueOrDefault("Hands"); //CP14 hands displacements
// add the new layers
foreach (var (key, layerData) in ev.Layers)
{
@@ -350,38 +348,9 @@ namespace Content.Client.Hands.Systems
sprite.LayerSetData(index, layerData);
//CP14 Hands displacement maps
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 inhand layers DISPLACEMENT: {displacementKey}.");
continue;
}
var displacementDataLayer = displacementData.Layer;
var actualRSI = sprite.LayerGetActualRSI(index);
if (actualRSI != null)
{
var layerSize = actualRSI.Size;
if (layerSize.X == 48 && displacementData.Layer48 != null)
displacementDataLayer = displacementData.Layer48;
}
var displacementLayer = _serialization.CreateCopy(displacementDataLayer, notNullableOverride: true);
displacementLayer.CopyToShaderParameters!.LayerKey = key;
// Add before main layer for this item.
sprite.AddLayer(displacementLayer, index);
sprite.LayerMapSet(displacementKey, index);
revealedLayers.Add(displacementKey);
}
//CP14 Hands displacement maps - end
//Add displacement maps
if (handComp.HandDisplacement is not null)
_displacement.TryAddDisplacement(handComp.HandDisplacement, sprite, index, key, revealedLayers);
}
RaiseLocalEvent(held, new HeldVisualsUpdatedEvent(uid, revealedLayers), true);

View File

@@ -1,6 +1,6 @@
using Content.Shared.MedicalScanner;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.HealthAnalyzer.UI
{
@@ -17,12 +17,9 @@ namespace Content.Client.HealthAnalyzer.UI
protected override void Open()
{
base.Open();
_window = new HealthAnalyzerWindow
{
Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName,
};
_window.OnClose += Close;
_window.OpenCentered();
_window = this.CreateWindow<HealthAnalyzerWindow>();
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
}
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
@@ -35,17 +32,5 @@ namespace Content.Client.HealthAnalyzer.UI
_window.Populate(cast);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
if (_window != null)
_window.OnClose -= Close;
_window?.Dispose();
}
}
}

View File

@@ -85,8 +85,19 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
if (protoId == null)
return;
//if (sexMorph)
// protoId = HumanoidVisualLayersExtension.GetSexMorph(key, component.Sex, protoId);
//CP14 female bodies support
if (sexMorph)
protoId = HumanoidVisualLayersExtension.GetSexMorph(key, component.Sex, protoId);
{
var tempProto = HumanoidVisualLayersExtension.GetSexMorph(key, component.Sex, protoId);
if (_prototypeManager.TryIndex<HumanoidSpeciesSpriteLayer>(tempProto, out _))
{
protoId = tempProto;
}
}
//CP14 female bodies support end
var proto = _prototypeManager.Index<HumanoidSpeciesSpriteLayer>(protoId);
component.BaseLayers[key] = proto;

View File

@@ -1,5 +1,6 @@
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings;
using Robust.Client.UserInterface;
namespace Content.Client.Humanoid;
@@ -20,8 +21,7 @@ public sealed class HumanoidMarkingModifierBoundUserInterface : BoundUserInterfa
{
base.Open();
_window = new();
_window.OnClose += Close;
_window = this.CreateWindow<HumanoidMarkingModifierWindow>();
_window.OnMarkingAdded += SendMarkingSet;
_window.OnMarkingRemoved += SendMarkingSet;
_window.OnMarkingColorChange += SendMarkingSetNoResend;

View File

@@ -0,0 +1,29 @@
using Content.Shared.IconSmoothing;
using Robust.Client.GameObjects;
namespace Content.Client.IconSmoothing;
public sealed class ClientRandomIconSmoothSystem : SharedRandomIconSmoothSystem
{
[Dependency] private readonly IconSmoothSystem _iconSmooth = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RandomIconSmoothComponent, AppearanceChangeEvent>(OnAppearanceChange);
}
private void OnAppearanceChange(Entity<RandomIconSmoothComponent> ent, ref AppearanceChangeEvent args)
{
if (!TryComp<IconSmoothComponent>(ent, out var smooth))
return;
if (!_appearance.TryGetData<string>(ent, RandomIconSmoothState.State, out var state, args.Component))
return;
smooth.StateBase = state;
_iconSmooth.SetStateBase(ent, smooth, state);
}
}

View File

@@ -30,7 +30,7 @@ namespace Content.Client.IconSmoothing
/// Prepended to the RSI state.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("base")]
public string StateBase { get; private set; } = string.Empty;
public string StateBase { get; set; } = string.Empty;
[DataField("shader", customTypeSerializer:typeof(PrototypeIdSerializer<ShaderPrototype>))]
public string? Shader;

View File

@@ -55,6 +55,33 @@ namespace Content.Client.IconSmoothing
if (component.Mode != IconSmoothingMode.Corners || !TryComp(uid, out SpriteComponent? sprite))
return;
SetCornerLayers(sprite, component);
if (component.Shader != null)
{
sprite.LayerSetShader(CornerLayers.SE, component.Shader);
sprite.LayerSetShader(CornerLayers.NE, component.Shader);
sprite.LayerSetShader(CornerLayers.NW, component.Shader);
sprite.LayerSetShader(CornerLayers.SW, component.Shader);
}
}
public void SetStateBase(EntityUid uid, IconSmoothComponent component, string newState)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;
component.StateBase = newState;
SetCornerLayers(sprite, component);
}
private void SetCornerLayers(SpriteComponent sprite, IconSmoothComponent component)
{
sprite.LayerMapRemove(CornerLayers.SE);
sprite.LayerMapRemove(CornerLayers.NE);
sprite.LayerMapRemove(CornerLayers.NW);
sprite.LayerMapRemove(CornerLayers.SW);
var state0 = $"{component.StateBase}0";
sprite.LayerMapSet(CornerLayers.SE, sprite.AddLayerState(state0));
sprite.LayerSetDirOffset(CornerLayers.SE, DirectionOffset.None);
@@ -64,14 +91,6 @@ namespace Content.Client.IconSmoothing
sprite.LayerSetDirOffset(CornerLayers.NW, DirectionOffset.Flip);
sprite.LayerMapSet(CornerLayers.SW, sprite.AddLayerState(state0));
sprite.LayerSetDirOffset(CornerLayers.SW, DirectionOffset.Clockwise);
if (component.Shader != null)
{
sprite.LayerSetShader(CornerLayers.SE, component.Shader);
sprite.LayerSetShader(CornerLayers.NE, component.Shader);
sprite.LayerSetShader(CornerLayers.NW, component.Shader);
sprite.LayerSetShader(CornerLayers.SW, component.Shader);
}
}
private void OnShutdown(EntityUid uid, IconSmoothComponent component, ComponentShutdown args)

View File

@@ -11,7 +11,9 @@ public sealed partial class BandMenu : DefaultWindow
{
private readonly InstrumentBoundUserInterface _owner;
public BandMenu(InstrumentBoundUserInterface owner) : base()
public EntityUid? Master;
public BandMenu(InstrumentBoundUserInterface owner)
{
RobustXamlLoader.Load(this);
@@ -40,7 +42,7 @@ public sealed partial class BandMenu : DefaultWindow
{
var uid = entManager.GetEntity(nent);
var item = BandList.AddItem(name, null, true, uid);
item.Selected = _owner.Instrument?.Master == uid;
item.Selected = Master == uid;
}
}
}

View File

@@ -51,7 +51,7 @@ public sealed partial class ChannelsMenu : DefaultWindow
}
}
public void Populate()
public void Populate(InstrumentComponent? instrument)
{
ChannelList.Clear();
@@ -60,7 +60,8 @@ public sealed partial class ChannelsMenu : DefaultWindow
var item = ChannelList.AddItem(_owner.Loc.GetString("instrument-component-channel-name",
("number", i)), null, true, i);
item.Selected = !_owner.Instrument?.FilteredChannels[i] ?? false;
item.Selected = !instrument?.FilteredChannels[i] ?? false;
}
}
}

View File

@@ -24,8 +24,6 @@ namespace Content.Client.Instruments.UI
[ViewVariables] private BandMenu? _bandMenu;
[ViewVariables] private ChannelsMenu? _channelsMenu;
[ViewVariables] public InstrumentComponent? Instrument { get; private set; }
public InstrumentBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
@@ -43,14 +41,20 @@ namespace Content.Client.Instruments.UI
protected override void Open()
{
if (!EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument))
return;
_instrumentMenu = this.CreateWindow<InstrumentMenu>();
_instrumentMenu.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
Instrument = instrument;
_instrumentMenu = new InstrumentMenu(this);
_instrumentMenu.OnClose += Close;
_instrumentMenu.OnOpenBand += OpenBandMenu;
_instrumentMenu.OnOpenChannels += OpenChannelsMenu;
_instrumentMenu.OnCloseChannels += CloseChannelsMenu;
_instrumentMenu.OnCloseBands += CloseBandMenu;
_instrumentMenu.OpenCentered();
_instrumentMenu.SetMIDI(MidiManager.IsAvailable);
if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument))
{
_instrumentMenu.SetInstrument((Owner, instrument));
}
}
protected override void Dispose(bool disposing)
@@ -58,7 +62,12 @@ namespace Content.Client.Instruments.UI
base.Dispose(disposing);
if (!disposing)
return;
_instrumentMenu?.Dispose();
if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument))
{
_instrumentMenu?.RemoveInstrument(instrument);
}
_bandMenu?.Dispose();
_channelsMenu?.Dispose();
}
@@ -72,6 +81,11 @@ namespace Content.Client.Instruments.UI
{
_bandMenu ??= new BandMenu(this);
if (EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument))
{
_bandMenu.Master = instrument.Master;
}
// Refresh cache...
RefreshBands();
@@ -87,7 +101,9 @@ namespace Content.Client.Instruments.UI
public void OpenChannelsMenu()
{
_channelsMenu ??= new ChannelsMenu(this);
_channelsMenu.Populate();
EntMan.TryGetComponent(Owner, out InstrumentComponent? instrument);
_channelsMenu.Populate(instrument);
_channelsMenu.OpenCenteredRight();
}

View File

@@ -1,7 +1,10 @@
using System.IO;
using System.Numerics;
using System.Threading.Tasks;
using Content.Client.Interactable;
using Content.Shared.ActionBlocker;
using Robust.Client.AutoGenerated;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
@@ -16,33 +19,23 @@ namespace Content.Client.Instruments.UI
[GenerateTypedNameReferences]
public sealed partial class InstrumentMenu : DefaultWindow
{
private readonly InstrumentBoundUserInterface _owner;
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IFileDialogManager _dialogs = default!;
[Dependency] private readonly IPlayerManager _player = default!;
private bool _isMidiFileDialogueWindowOpen;
public InstrumentMenu(InstrumentBoundUserInterface owner)
public event Action? OnOpenBand;
public event Action? OnOpenChannels;
public event Action? OnCloseBands;
public event Action? OnCloseChannels;
public EntityUid Entity;
public InstrumentMenu()
{
RobustXamlLoader.Load(this);
_owner = owner;
if (_owner.Instrument != null)
{
_owner.Instrument.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded;
Title = _owner.Entities.GetComponent<MetaDataComponent>(_owner.Owner).EntityName;
LoopButton.Disabled = !_owner.Instrument.IsMidiOpen;
LoopButton.Pressed = _owner.Instrument.LoopMidi;
ChannelsButton.Disabled = !_owner.Instrument.IsRendererAlive;
StopButton.Disabled = !_owner.Instrument.IsMidiOpen;
PlaybackSlider.MouseFilter = _owner.Instrument.IsMidiOpen ? MouseFilterMode.Pass : MouseFilterMode.Ignore;
}
if (!_owner.MidiManager.IsAvailable)
{
UnavailableOverlay.Visible = true;
// We return early as to not give the buttons behavior.
return;
}
IoCManager.InjectDependencies(this);
InputButton.OnToggled += MidiInputButtonOnOnToggled;
BandButton.OnPressed += BandButtonOnPressed;
@@ -57,12 +50,34 @@ namespace Content.Client.Instruments.UI
MinSize = SetSize = new Vector2(400, 150);
}
public void SetInstrument(Entity<InstrumentComponent> entity)
{
Entity = entity;
var component = entity.Comp;
component.OnMidiPlaybackEnded += InstrumentOnMidiPlaybackEnded;
LoopButton.Disabled = !component.IsMidiOpen;
LoopButton.Pressed = component.LoopMidi;
ChannelsButton.Disabled = !component.IsRendererAlive;
StopButton.Disabled = !component.IsMidiOpen;
PlaybackSlider.MouseFilter = component.IsMidiOpen ? MouseFilterMode.Pass : MouseFilterMode.Ignore;
}
public void RemoveInstrument(InstrumentComponent component)
{
component.OnMidiPlaybackEnded -= InstrumentOnMidiPlaybackEnded;
}
public void SetMIDI(bool available)
{
UnavailableOverlay.Visible = !available;
}
private void BandButtonOnPressed(ButtonEventArgs obj)
{
if (!PlayCheck())
return;
_owner.OpenBandMenu();
OnOpenBand?.Invoke();
}
private void BandButtonOnToggled(ButtonToggledEventArgs obj)
@@ -70,12 +85,15 @@ namespace Content.Client.Instruments.UI
if (obj.Pressed)
return;
_owner.Instruments.SetMaster(_owner.Owner, null);
if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument))
{
_entManager.System<InstrumentSystem>().SetMaster(Entity, instrument.Master);
}
}
private void ChannelsButtonOnPressed(ButtonEventArgs obj)
{
_owner.OpenChannelsMenu();
OnOpenChannels?.Invoke();
}
private void InstrumentOnMidiPlaybackEnded()
@@ -85,8 +103,10 @@ namespace Content.Client.Instruments.UI
public void MidiPlaybackSetButtonsDisabled(bool disabled)
{
if(disabled)
_owner.CloseChannelsMenu();
if (disabled)
{
OnCloseChannels?.Invoke();
}
LoopButton.Disabled = disabled;
StopButton.Disabled = disabled;
@@ -100,7 +120,7 @@ namespace Content.Client.Instruments.UI
if (_isMidiFileDialogueWindowOpen)
return;
_owner.CloseBandMenu();
OnCloseBands?.Invoke();
var filters = new FileDialogFilters(new FileDialogFilters.Group("mid", "midi"));
@@ -108,7 +128,7 @@ namespace Content.Client.Instruments.UI
// or focus the previously-opened window.
_isMidiFileDialogueWindowOpen = true;
await using var file = await _owner.FileDialogManager.OpenFile(filters);
await using var file = await _dialogs.OpenFile(filters);
_isMidiFileDialogueWindowOpen = false;
@@ -129,9 +149,18 @@ namespace Content.Client.Instruments.UI
await file.CopyToAsync(memStream);
if (_owner.Instrument is not {} instrument
|| !_owner.Instruments.OpenMidi(_owner.Owner, memStream.GetBuffer().AsSpan(0, (int) memStream.Length), instrument))
if (!_entManager.TryGetComponent<InstrumentComponent>(Entity, out var instrument))
{
return;
}
if (!_entManager.System<InstrumentSystem>()
.OpenMidi(Entity,
memStream.GetBuffer().AsSpan(0, (int) memStream.Length),
instrument))
{
return;
}
MidiPlaybackSetButtonsDisabled(false);
if (InputButton.Pressed)
@@ -140,7 +169,7 @@ namespace Content.Client.Instruments.UI
private void MidiInputButtonOnOnToggled(ButtonToggledEventArgs obj)
{
_owner.CloseBandMenu();
OnCloseBands?.Invoke();
if (obj.Pressed)
{
@@ -148,109 +177,99 @@ namespace Content.Client.Instruments.UI
return;
MidiStopButtonOnPressed(null);
if(_owner.Instrument is {} instrument)
_owner.Instruments.OpenInput(_owner.Owner, instrument);
if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument))
_entManager.System<InstrumentSystem>().OpenInput(Entity, instrument);
}
else if (_owner.Instrument is { } instrument)
else
{
_owner.Instruments.CloseInput(_owner.Owner, false, instrument);
_owner.CloseChannelsMenu();
_entManager.System<InstrumentSystem>().CloseInput(Entity, false);
OnCloseChannels?.Invoke();
}
}
private bool PlayCheck()
{
// TODO all of these checks should also be done server-side.
var instrumentEnt = _owner.Owner;
var instrument = _owner.Instrument;
if (instrument == null)
if (!_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument))
return false;
var localEntity = _owner.PlayerManager.LocalEntity;
var localEntity = _player.LocalEntity;
// If we don't have a player or controlled entity, we return.
if (localEntity == null)
return false;
// By default, allow an instrument to play itself and skip all other checks
if (localEntity == instrumentEnt)
if (localEntity == Entity)
return true;
var container = _owner.Entities.System<SharedContainerSystem>();
var container = _entManager.System<SharedContainerSystem>();
// If we're a handheld instrument, we might be in a container. Get it just in case.
container.TryGetContainingContainer(instrumentEnt, out var conMan);
container.TryGetContainingContainer(Entity, out var conMan);
// If the instrument is handheld and we're not holding it, we return.
if ((instrument.Handheld && (conMan == null || conMan.Owner != localEntity)))
if (instrument.Handheld && (conMan == null || conMan.Owner != localEntity))
return false;
if (!_owner.ActionBlocker.CanInteract(localEntity.Value, instrumentEnt))
if (!_entManager.System<ActionBlockerSystem>().CanInteract(localEntity.Value, Entity))
return false;
// We check that we're in range unobstructed just in case.
return _owner.Interactions.InRangeUnobstructed(localEntity.Value, instrumentEnt);
return _entManager.System<InteractionSystem>().InRangeUnobstructed(localEntity.Value, Entity);
}
private void MidiStopButtonOnPressed(ButtonEventArgs? obj)
{
MidiPlaybackSetButtonsDisabled(true);
if (_owner.Instrument is not {} instrument)
return;
_owner.Instruments.CloseMidi(_owner.Owner, false, instrument);
_owner.CloseChannelsMenu();
_entManager.System<InstrumentSystem>().CloseMidi(Entity, false);
OnCloseChannels?.Invoke();
}
private void MidiLoopButtonOnOnToggled(ButtonToggledEventArgs obj)
{
if (_owner.Instrument == null)
return;
var instrument = _entManager.System<InstrumentSystem>();
_owner.Instrument.LoopMidi = obj.Pressed;
_owner.Instruments.UpdateRenderer(_owner.Owner, _owner.Instrument);
if (_entManager.TryGetComponent(Entity, out InstrumentComponent? instrumentComp))
{
instrumentComp.LoopMidi = obj.Pressed;
}
instrument.UpdateRenderer(Entity);
}
private void PlaybackSliderSeek(Range _)
{
// Do not seek while still grabbing.
if (PlaybackSlider.Grabbed || _owner.Instrument is not {} instrument)
if (PlaybackSlider.Grabbed)
return;
_owner.Instruments.SetPlayerTick(_owner.Owner, (int)Math.Ceiling(PlaybackSlider.Value), instrument);
_entManager.System<InstrumentSystem>().SetPlayerTick(Entity, (int)Math.Ceiling(PlaybackSlider.Value));
}
private void PlaybackSliderKeyUp(GUIBoundKeyEventArgs args)
{
if (args.Function != EngineKeyFunctions.UIClick || _owner.Instrument is not {} instrument)
if (args.Function != EngineKeyFunctions.UIClick)
return;
_owner.Instruments.SetPlayerTick(_owner.Owner, (int)Math.Ceiling(PlaybackSlider.Value), instrument);
}
public override void Close()
{
base.Close();
_owner.CloseBandMenu();
_owner.CloseChannelsMenu();
_entManager.System<InstrumentSystem>().SetPlayerTick(Entity, (int)Math.Ceiling(PlaybackSlider.Value));
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if (_owner.Instrument == null)
if (!_entManager.TryGetComponent(Entity, out InstrumentComponent? instrument))
return;
var hasMaster = _owner.Instrument.Master != null;
var hasMaster = instrument.Master != null;
BandButton.ToggleMode = hasMaster;
BandButton.Pressed = hasMaster;
BandButton.Disabled = _owner.Instrument.IsMidiOpen || _owner.Instrument.IsInputOpen;
ChannelsButton.Disabled = !_owner.Instrument.IsRendererAlive;
BandButton.Disabled = instrument.IsMidiOpen || instrument.IsInputOpen;
ChannelsButton.Disabled = !instrument.IsRendererAlive;
if (!_owner.Instrument.IsMidiOpen)
if (!instrument.IsMidiOpen)
{
PlaybackSlider.MaxValue = 1;
PlaybackSlider.SetValueWithoutEvent(0);
@@ -260,8 +279,8 @@ namespace Content.Client.Instruments.UI
if (PlaybackSlider.Grabbed)
return;
PlaybackSlider.MaxValue = _owner.Instrument.PlayerTotalTick;
PlaybackSlider.SetValueWithoutEvent(_owner.Instrument.PlayerTick);
PlaybackSlider.MaxValue = instrument.PlayerTotalTick;
PlaybackSlider.SetValueWithoutEvent(instrument.PlayerTick);
}
}
}

View File

@@ -41,7 +41,7 @@ namespace Content.Client.Inventory
public const string HiddenPocketEntityId = "StrippingHiddenEntity";
[ViewVariables]
private readonly StrippingMenu? _strippingMenu;
private StrippingMenu? _strippingMenu;
[ViewVariables]
private readonly EntityUid _virtualHiddenEntity;
@@ -51,33 +51,30 @@ namespace Content.Client.Inventory
_examine = EntMan.System<ExamineSystem>();
_inv = EntMan.System<InventorySystem>();
_cuffable = EntMan.System<SharedCuffableSystem>();
// TODO update name when identity changes
var title = Loc.GetString("strippable-bound-user-interface-stripping-menu-title", ("ownerName", Identity.Name(Owner, EntMan)));
_strippingMenu = new StrippingMenu(title, this);
_strippingMenu.OnClose += Close;
// TODO use global entity
// BUIs are opened and closed while applying comp sates, so spawning entities here is probably not the best idea.
_virtualHiddenEntity = EntMan.SpawnEntity(HiddenPocketEntityId, MapCoordinates.Nullspace);
}
protected override void Open()
{
base.Open();
_strippingMenu = this.CreateWindow<StrippingMenu>();
_strippingMenu.OnDirty += UpdateMenu;
_strippingMenu.Title = Loc.GetString("strippable-bound-user-interface-stripping-menu-title", ("ownerName", Identity.Name(Owner, EntMan)));
_strippingMenu?.OpenCenteredLeft();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
EntMan.DeleteEntity(_virtualHiddenEntity);
if (!disposing)
return;
_strippingMenu?.Dispose();
if (_strippingMenu != null)
_strippingMenu.OnDirty -= UpdateMenu;
EntMan.DeleteEntity(_virtualHiddenEntity);
base.Dispose(disposing);
}
public void DirtyMenu()

View File

@@ -12,42 +12,34 @@ namespace Content.Client.Kitchen.UI
[GenerateTypedNameReferences]
public sealed partial class GrinderMenu : FancyWindow
{
private readonly IEntityManager _entityManager;
private readonly IPrototypeManager _prototypeManager;
private readonly ReagentGrinderBoundUserInterface _owner;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private readonly Dictionary<int, EntityUid> _chamberVisualContents = new();
public GrinderMenu(ReagentGrinderBoundUserInterface owner, IEntityManager entityManager, IPrototypeManager prototypeManager)
public event Action? OnToggleAuto;
public event Action? OnGrind;
public event Action? OnJuice;
public event Action? OnEjectAll;
public event Action? OnEjectBeaker;
public event Action<EntityUid>? OnEjectChamber;
public GrinderMenu()
{
RobustXamlLoader.Load(this);
_entityManager = entityManager;
_prototypeManager = prototypeManager;
_owner = owner;
AutoModeButton.OnPressed += owner.ToggleAutoMode;
GrindButton.OnPressed += owner.StartGrinding;
JuiceButton.OnPressed += owner.StartJuicing;
ChamberContentBox.EjectButton.OnPressed += owner.EjectAll;
BeakerContentBox.EjectButton.OnPressed += owner.EjectBeaker;
IoCManager.InjectDependencies(this);
AutoModeButton.OnPressed += _ => OnToggleAuto?.Invoke();
GrindButton.OnPressed += _ => OnGrind?.Invoke();
JuiceButton.OnPressed += _ => OnJuice?.Invoke();
ChamberContentBox.EjectButton.OnPressed += _ => OnEjectAll?.Invoke();
BeakerContentBox.EjectButton.OnPressed += _ => OnEjectBeaker?.Invoke();
ChamberContentBox.BoxContents.OnItemSelected += OnChamberBoxContentsItemSelected;
BeakerContentBox.BoxContents.SelectMode = ItemList.ItemListSelectMode.None;
}
private void OnChamberBoxContentsItemSelected(ItemList.ItemListSelectedEventArgs args)
{
_owner.EjectChamberContent(_chamberVisualContents[args.ItemIndex]);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_chamberVisualContents.Clear();
GrindButton.OnPressed -= _owner.StartGrinding;
JuiceButton.OnPressed -= _owner.StartJuicing;
ChamberContentBox.EjectButton.OnPressed -= _owner.EjectAll;
BeakerContentBox.EjectButton.OnPressed -= _owner.EjectBeaker;
ChamberContentBox.BoxContents.OnItemSelected -= OnChamberBoxContentsItemSelected;
OnEjectChamber?.Invoke(_chamberVisualContents[args.ItemIndex]);
}
public void UpdateState(ReagentGrinderInterfaceState state)

View File

@@ -3,6 +3,7 @@ using Content.Shared.Kitchen.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Timing;
@@ -19,28 +20,15 @@ namespace Content.Client.Kitchen.UI
[ViewVariables]
private readonly Dictionary<int, ReagentQuantity> _reagents = new();
[Dependency] private readonly IGameTiming _gameTiming = default!;
public MicrowaveUpdateUserInterfaceState currentState = default!;
private IEntityManager _entManager;
public MicrowaveBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
_entManager = IoCManager.Resolve<IEntityManager>();
}
public TimeSpan GetCurrentTime()
{
return _gameTiming.CurTime;
}
protected override void Open()
{
base.Open();
_menu = new MicrowaveMenu(this);
_menu.OpenCentered();
_menu.OnClose += Close;
_menu = this.CreateWindow<MicrowaveMenu>();
_menu.StartButton.OnPressed += _ => SendPredictedMessage(new MicrowaveStartCookMessage());
_menu.EjectButton.OnPressed += _ => SendPredictedMessage(new MicrowaveEjectMessage());
_menu.IngredientsList.OnItemSelected += args =>
@@ -74,38 +62,23 @@ namespace Content.Client.Kitchen.UI
};
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
{
return;
}
_solids.Clear();
_menu?.Dispose();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is not MicrowaveUpdateUserInterfaceState cState)
if (state is not MicrowaveUpdateUserInterfaceState cState || _menu == null)
{
return;
}
_menu.IsBusy = cState.IsMicrowaveBusy;
_menu.CurrentCooktimeEnd = cState.CurrentCookTimeEnd;
_menu?.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0);
currentState = cState;
_menu.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0);
// TODO move this to a component state and ensure the net ids.
RefreshContentsDisplay(_entManager.GetEntityArray(cState.ContainedSolids));
if (_menu == null) return;
RefreshContentsDisplay(EntMan.GetEntityArray(cState.ContainedSolids));
//Set the cook time info label
var cookTime = cState.ActiveButtonIndex == 0
var cookTime = cState.ActiveButtonIndex == 0
? Loc.GetString("microwave-menu-instant-button")
: cState.CurrentCookTime.ToString();

View File

@@ -9,22 +9,21 @@ namespace Content.Client.Kitchen.UI
[GenerateTypedNameReferences]
public sealed partial class MicrowaveMenu : FancyWindow
{
public sealed class MicrowaveCookTimeButton : Button
{
public uint CookTime;
}
[Dependency] private readonly IGameTiming _timing = default!;
public event Action<BaseButton.ButtonEventArgs, int>? OnCookTimeSelected;
public ButtonGroup CookTimeButtonGroup { get; }
private readonly MicrowaveBoundUserInterface _owner;
public MicrowaveMenu(MicrowaveBoundUserInterface owner)
public bool IsBusy;
public TimeSpan CurrentCooktimeEnd;
public MicrowaveMenu()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
CookTimeButtonGroup = new ButtonGroup();
InstantCookButton.Group = CookTimeButtonGroup;
_owner = owner;
InstantCookButton.OnPressed += args =>
{
OnCookTimeSelected?.Invoke(args, 0);
@@ -65,14 +64,20 @@ namespace Content.Client.Kitchen.UI
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if(!_owner.currentState.IsMicrowaveBusy)
if (!IsBusy)
return;
if(_owner.currentState.CurrentCookTimeEnd > _owner.GetCurrentTime())
if (CurrentCooktimeEnd > _timing.CurTime)
{
CookTimeInfoLabel.Text = Loc.GetString("microwave-bound-user-interface-cook-time-label",
("time",_owner.currentState.CurrentCookTimeEnd.Subtract(_owner.GetCurrentTime()).Seconds));
("time", CurrentCooktimeEnd.Subtract(_timing.CurTime).Seconds));
}
}
public sealed class MicrowaveCookTimeButton : Button
{
public uint CookTime;
}
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Kitchen;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Prototypes;
@@ -8,8 +9,6 @@ namespace Content.Client.Kitchen.UI
{
public sealed class ReagentGrinderBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[ViewVariables]
private GrinderMenu? _menu;
@@ -21,20 +20,13 @@ namespace Content.Client.Kitchen.UI
{
base.Open();
_menu = new GrinderMenu(this, EntMan, _prototypeManager);
_menu.OpenCentered();
_menu.OnClose += Close;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
{
return;
}
_menu?.Dispose();
_menu = this.CreateWindow<GrinderMenu>();
_menu.OnToggleAuto += ToggleAutoMode;
_menu.OnGrind += StartGrinding;
_menu.OnJuice += StartJuicing;
_menu.OnEjectAll += EjectAll;
_menu.OnEjectBeaker += EjectBeaker;
_menu.OnEjectChamber += EjectChamberContent;
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -52,27 +44,27 @@ namespace Content.Client.Kitchen.UI
_menu?.HandleMessage(message);
}
public void ToggleAutoMode(BaseButton.ButtonEventArgs args)
public void ToggleAutoMode()
{
SendMessage(new ReagentGrinderToggleAutoModeMessage());
}
public void StartGrinding(BaseButton.ButtonEventArgs? _ = null)
public void StartGrinding()
{
SendMessage(new ReagentGrinderStartMessage(GrinderProgram.Grind));
}
public void StartJuicing(BaseButton.ButtonEventArgs? _ = null)
public void StartJuicing()
{
SendMessage(new ReagentGrinderStartMessage(GrinderProgram.Juice));
}
public void EjectAll(BaseButton.ButtonEventArgs? _ = null)
public void EjectAll()
{
SendMessage(new ReagentGrinderEjectChamberAllMessage());
}
public void EjectBeaker(BaseButton.ButtonEventArgs? _ = null)
public void EjectBeaker()
{
SendMessage(new ItemSlotButtonPressedEvent(SharedReagentGrinder.BeakerSlotId));
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Labels;
using Content.Shared.Labels.Components;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Labels.UI
{
@@ -23,13 +24,8 @@ namespace Content.Client.Labels.UI
{
base.Open();
_window = new HandLabelerWindow();
if (State != null)
UpdateState(State);
_window = this.CreateWindow<HandLabelerWindow>();
_window.OpenCentered();
_window.OnClose += Close;
_window.OnLabelChanged += OnLabelChanged;
Reload();
}
@@ -51,13 +47,5 @@ namespace Content.Client.Labels.UI
_window.SetCurrentLabel(component.AssignedLabel);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Lathe;
using Content.Shared.Research.Components;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
namespace Content.Client.Lathe.UI
{
@@ -17,9 +18,9 @@ namespace Content.Client.Lathe.UI
{
base.Open();
_menu = new LatheMenu(this);
_menu.OnClose += Close;
_menu = this.CreateWindow<LatheMenu>();
_menu.SetEntity(Owner);
_menu.OpenCenteredRight();
_menu.OnServerListButtonPressed += _ =>
{
@@ -30,8 +31,6 @@ namespace Content.Client.Lathe.UI
{
SendMessage(new LatheQueueRecipeMessage(recipe, amount));
};
_menu.OpenCenteredRight();
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -50,13 +49,5 @@ namespace Content.Client.Lathe.UI
break;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Dispose();
}
}
}

View File

@@ -1,3 +1,4 @@
using System.Buffers;
using System.Linq;
using System.Text;
using Content.Client.Materials;
@@ -21,9 +22,7 @@ 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;
private readonly MaterialStorageSystem _materialStorage;
@@ -37,9 +36,10 @@ public sealed partial class LatheMenu : DefaultWindow
public ProtoId<LatheCategoryPrototype>? CurrentCategory;
public LatheMenu(LatheBoundUserInterface owner)
public EntityUid Entity;
public LatheMenu()
{
_owner = owner.Owner;
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
@@ -47,8 +47,6 @@ public sealed partial class LatheMenu : DefaultWindow
_lathe = _entityManager.System<LatheSystem>();
_materialStorage = _entityManager.System<MaterialStorageSystem>();
Title = _entityManager.GetComponent<MetaDataComponent>(owner.Owner).EntityName;
SearchBar.OnTextChanged += _ =>
{
PopulateRecipes();
@@ -61,8 +59,13 @@ public sealed partial class LatheMenu : DefaultWindow
FilterOption.OnItemSelected += OnItemSelected;
ServerListButton.OnPressed += a => OnServerListButtonPressed?.Invoke(a);
}
if (_entityManager.TryGetComponent<LatheComponent>(owner.Owner, out var latheComponent))
public void SetEntity(EntityUid uid)
{
Entity = uid;
if (_entityManager.TryGetComponent<LatheComponent>(Entity, out var latheComponent))
{
if (!latheComponent.DynamicRecipes.Any())
{
@@ -70,7 +73,7 @@ public sealed partial class LatheMenu : DefaultWindow
}
}
MaterialsList.SetOwner(owner.Owner);
MaterialsList.SetOwner(Entity);
}
/// <summary>
@@ -103,13 +106,15 @@ public sealed partial class LatheMenu : DefaultWindow
var sortedRecipesToShow = recipesToShow.OrderBy(p => p.Name);
RecipeList.Children.Clear();
_entityManager.TryGetComponent(Entity, out LatheComponent? lathe);
foreach (var prototype in sortedRecipesToShow)
{
EntityPrototype? recipeProto = null;
if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto) && entityProto != null)
if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto))
recipeProto = entityProto;
var canProduce = _lathe.CanProduce(_owner, prototype, quantity);
var canProduce = _lathe.CanProduce(Entity, prototype, quantity, component: lathe);
var control = new RecipeControl(prototype, () => GenerateTooltipText(prototype), canProduce, recipeProto);
control.OnButtonPressed += s =>
@@ -125,19 +130,20 @@ public sealed partial class LatheMenu : DefaultWindow
private string GenerateTooltipText(LatheRecipePrototype prototype)
{
StringBuilder sb = new();
var multiplier = _entityManager.GetComponent<LatheComponent>(Entity).MaterialUseMultiplier;
foreach (var (id, amount) in prototype.RequiredMaterials)
{
if (!_prototypeManager.TryIndex<MaterialPrototype>(id, out var proto))
continue;
var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, _entityManager.GetComponent<LatheComponent>(_owner).MaterialUseMultiplier);
var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, multiplier);
var sheetVolume = _materialStorage.GetSheetVolume(proto);
var unit = Loc.GetString(proto.Unit);
var sheets = adjustedAmount / (float) sheetVolume;
var availableAmount = _materialStorage.GetMaterialAmount(_owner, id);
var availableAmount = _materialStorage.GetMaterialAmount(Entity, id);
var missingAmount = Math.Max(0, adjustedAmount - availableAmount);
var missingSheets = missingAmount / (float) sheetVolume;

View File

@@ -1,5 +1,6 @@
using Content.Shared.MachineLinking;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Shared.Timing;
namespace Content.Client.MachineLinking.UI;
@@ -19,19 +20,14 @@ public sealed class SignalTimerBoundUserInterface : BoundUserInterface
{
base.Open();
_window = new SignalTimerWindow(this);
if (State != null)
UpdateState(State);
_window.OpenCentered();
_window.OnClose += Close;
_window = this.CreateWindow<SignalTimerWindow>();
_window.OnStartTimer += StartTimer;
_window.OnCurrentTextChanged += OnTextChanged;
_window.OnCurrentDelayMinutesChanged += OnDelayChanged;
_window.OnCurrentDelaySecondsChanged += OnDelayChanged;
}
public void OnStartTimer()
public void StartTimer()
{
SendMessage(new SignalTimerStartMessage());
}
@@ -48,11 +44,6 @@ public sealed class SignalTimerBoundUserInterface : BoundUserInterface
SendMessage(new SignalTimerDelayChangedMessage(_window.GetDelay()));
}
public TimeSpan GetCurrentTime()
{
return _gameTiming.CurTime;
}
/// <summary>
/// Update the UI state based on server-sent info
/// </summary>
@@ -72,11 +63,4 @@ public sealed class SignalTimerBoundUserInterface : BoundUserInterface
_window.SetTimerStarted(cast.TimerStarted);
_window.SetHasAccess(cast.HasAccess);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_window?.Dispose();
}
}

View File

@@ -9,42 +9,44 @@ namespace Content.Client.MachineLinking.UI;
[GenerateTypedNameReferences]
public sealed partial class SignalTimerWindow : DefaultWindow
{
[Dependency] private readonly IGameTiming _timing = default!;
private const int MaxTextLength = 5;
public event Action<string>? OnCurrentTextChanged;
public event Action<string>? OnCurrentDelayMinutesChanged;
public event Action<string>? OnCurrentDelaySecondsChanged;
private readonly SignalTimerBoundUserInterface _owner;
private TimeSpan? _triggerTime;
private bool _timerStarted;
public SignalTimerWindow(SignalTimerBoundUserInterface owner)
public event Action? OnStartTimer;
public SignalTimerWindow()
{
RobustXamlLoader.Load(this);
_owner = owner;
IoCManager.InjectDependencies(this);
CurrentTextEdit.OnTextChanged += e => OnCurrentTextChange(e.Text);
CurrentDelayEditMinutes.OnTextChanged += e => OnCurrentDelayMinutesChange(e.Text);
CurrentDelayEditSeconds.OnTextChanged += e => OnCurrentDelaySecondsChange(e.Text);
StartTimer.OnPressed += _ => OnStartTimer();
StartTimer.OnPressed += _ => StartTimerWeh();
}
public void OnStartTimer()
private void StartTimerWeh()
{
if (!_timerStarted)
{
_timerStarted = true;
_triggerTime = _owner.GetCurrentTime() + GetDelay();
_triggerTime = _timing.CurTime + GetDelay();
}
else
{
SetTimerStarted(false);
}
_owner.OnStartTimer();
OnStartTimer?.Invoke();
}
protected override void FrameUpdate(FrameEventArgs args)
@@ -54,9 +56,9 @@ public sealed partial class SignalTimerWindow : DefaultWindow
if (!_timerStarted || _triggerTime == null)
return;
if (_owner.GetCurrentTime() < _triggerTime.Value)
if (_timing.CurTime < _triggerTime.Value)
{
StartTimer.Text = TextScreenSystem.TimeToString(_triggerTime.Value - _owner.GetCurrentTime());
StartTimer.Text = TextScreenSystem.TimeToString(_triggerTime.Value - _timing.CurTime);
}
else
{

View File

@@ -1,6 +1,7 @@
using Content.Shared.Humanoid.Markings;
using Content.Shared.MagicMirror;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.MagicMirror;
@@ -17,7 +18,7 @@ public sealed class MagicMirrorBoundUserInterface : BoundUserInterface
{
base.Open();
_window = new();
_window = this.CreateWindow<MagicMirrorWindow>();
_window.OnHairSelected += tuple => SelectHair(MagicMirrorCategory.Hair, tuple.id, tuple.slot);
_window.OnHairColorChanged += args => ChangeColor(MagicMirrorCategory.Hair, args.marking, args.slot);
@@ -29,9 +30,6 @@ public sealed class MagicMirrorBoundUserInterface : BoundUserInterface
args => ChangeColor(MagicMirrorCategory.FacialHair, args.marking, args.slot);
_window.OnFacialHairSlotAdded += delegate () { AddSlot(MagicMirrorCategory.FacialHair); };
_window.OnFacialHairSlotRemoved += args => RemoveSlot(MagicMirrorCategory.FacialHair, args);
_window.OnClose += Close;
_window.OpenCentered();
}
private void SelectHair(MagicMirrorCategory category, string marking, int slot)
@@ -65,14 +63,5 @@ public sealed class MagicMirrorBoundUserInterface : BoundUserInterface
_window.UpdateState(data);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_window?.Dispose();
}
}

View File

@@ -1,6 +1,7 @@
using JetBrains.Annotations;
using Content.Shared.MassMedia.Systems;
using Content.Shared.MassMedia.Components;
using Robust.Client.UserInterface;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -9,8 +10,6 @@ namespace Content.Client.MassMedia.Ui;
[UsedImplicitly]
public sealed class NewsWriterBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
[ViewVariables]
private NewsWriterMenu? _menu;
@@ -21,10 +20,7 @@ public sealed class NewsWriterBoundUserInterface : BoundUserInterface
protected override void Open()
{
_menu = new NewsWriterMenu(_gameTiming);
_menu.OpenCentered();
_menu.OnClose += Close;
_menu = this.CreateWindow<NewsWriterMenu>();
_menu.ArticleEditorPanel.PublishButtonPressed += OnPublishButtonPressed;
_menu.DeleteButtonPressed += OnDeleteButtonPressed;
@@ -32,16 +28,6 @@ public sealed class NewsWriterBoundUserInterface : BoundUserInterface
SendMessage(new NewsWriterArticlesRequestMessage());
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Close();
_menu?.Dispose();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

View File

@@ -10,17 +10,17 @@ namespace Content.Client.MassMedia.Ui;
[GenerateTypedNameReferences]
public sealed partial class NewsWriterMenu : FancyWindow
{
private readonly IGameTiming _gameTiming;
[Dependency] private readonly IGameTiming _gameTiming = default!;
private TimeSpan? _nextPublish;
public event Action<int>? DeleteButtonPressed;
public NewsWriterMenu(IGameTiming gameTiming)
public NewsWriterMenu()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_gameTiming = gameTiming;
ContentsContainer.RectClipContent = false;
// Customize scrollbar width and margin. This is not possible in xaml

View File

@@ -3,6 +3,7 @@ using Content.Shared.Mech;
using Content.Shared.Mech.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Mech.Ui;
@@ -20,9 +21,8 @@ public sealed class MechBoundUserInterface : BoundUserInterface
{
base.Open();
_menu = new(Owner);
_menu.OnClose += Close;
_menu = this.CreateWindow<MechMenu>();
_menu.SetEntity(Owner);
_menu.OpenCenteredLeft();
_menu.OnRemoveButtonPressed += uid =>
@@ -60,16 +60,6 @@ public sealed class MechBoundUserInterface : BoundUserInterface
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Close();
}
public UIFragment? GetEquipmentUi(EntityUid? uid)
{
var component = EntMan.GetComponentOrNull<UIFragmentComponent>(uid);

View File

@@ -12,18 +12,20 @@ public sealed partial class MechMenu : FancyWindow
{
[Dependency] private readonly IEntityManager _ent = default!;
private readonly EntityUid _mech;
private EntityUid _mech;
public event Action<EntityUid>? OnRemoveButtonPressed;
public MechMenu(EntityUid mech)
public MechMenu()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
}
_mech = mech;
MechView.SetEntity(mech);
public void SetEntity(EntityUid uid)
{
MechView.SetEntity(uid);
_mech = uid;
}
public void UpdateMechStats()

View File

@@ -1,4 +1,5 @@
using Content.Shared.Medical.CrewMonitoring;
using Robust.Client.UserInterface;
namespace Content.Client.Medical.CrewMonitoring;
@@ -14,7 +15,7 @@ public sealed class CrewMonitoringBoundUserInterface : BoundUserInterface
protected override void Open()
{
EntityUid? gridUid = null;
string stationName = string.Empty;
var stationName = string.Empty;
if (EntMan.TryGetComponent<TransformComponent>(Owner, out var xform))
{
@@ -26,10 +27,8 @@ public sealed class CrewMonitoringBoundUserInterface : BoundUserInterface
}
}
_menu = new CrewMonitoringWindow(stationName, gridUid);
_menu.OpenCentered();
_menu.OnClose += Close;
_menu = this.CreateWindow<CrewMonitoringWindow>();
_menu.Set(stationName, gridUid);
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -44,13 +43,4 @@ public sealed class CrewMonitoringBoundUserInterface : BoundUserInterface
break;
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Dispose();
}
}

View File

@@ -23,22 +23,27 @@ namespace Content.Client.Medical.CrewMonitoring;
[GenerateTypedNameReferences]
public sealed partial class CrewMonitoringWindow : FancyWindow
{
private readonly IEntityManager _entManager;
private readonly IPrototypeManager _prototypeManager;
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private readonly SpriteSystem _spriteSystem;
private NetEntity? _trackedEntity;
private bool _tryToScrollToListFocus;
private Texture? _blipTexture;
public CrewMonitoringWindow(string stationName, EntityUid? mapUid)
public CrewMonitoringWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_entManager = IoCManager.Resolve<IEntityManager>();
_prototypeManager = IoCManager.Resolve<IPrototypeManager>();
_spriteSystem = _entManager.System<SpriteSystem>();
NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap;
}
public void Set(string stationName, EntityUid? mapUid)
{
_blipTexture = _spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png")));
if (_entManager.TryGetComponent<TransformComponent>(mapUid, out var xform))
@@ -49,8 +54,6 @@ public sealed partial class CrewMonitoringWindow : FancyWindow
StationName.AddStyleClass("LabelBig");
StationName.Text = stationName;
NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap;
NavMap.ForceNavMapUpdate();
}

View File

@@ -1,6 +1,7 @@
using Content.Client.NetworkConfigurator.Systems;
using Content.Shared.DeviceNetwork;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
namespace Content.Client.NetworkConfigurator;
@@ -35,14 +36,12 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
switch (UiKey)
{
case NetworkConfiguratorUiKey.List:
_listMenu = new NetworkConfiguratorListMenu(this);
_listMenu.OnClose += Close;
_listMenu = this.CreateWindow<NetworkConfiguratorListMenu>();
_listMenu.ClearButton.OnPressed += _ => OnClearButtonPressed();
_listMenu.OpenCenteredRight();
_listMenu.OnRemoveAddress += OnRemoveButtonPressed;
break;
case NetworkConfiguratorUiKey.Configure:
_configurationMenu = new NetworkConfiguratorConfigurationMenu();
_configurationMenu.OnClose += Close;
_configurationMenu = this.CreateWindow<NetworkConfiguratorConfigurationMenu>();
_configurationMenu.Set.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Set);
_configurationMenu.Add.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Add);
//_configurationMenu.Edit.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Edit);
@@ -50,12 +49,24 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
_configurationMenu.Copy.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Copy);
_configurationMenu.Show.OnPressed += OnShowPressed;
_configurationMenu.Show.Pressed = _netConfig.ConfiguredListIsTracked(Owner);
_configurationMenu.OpenCentered();
_configurationMenu.OnRemoveAddress += OnRemoveButtonPressed;
break;
case NetworkConfiguratorUiKey.Link:
_linkMenu = new NetworkConfiguratorLinkMenu(this);
_linkMenu.OnClose += Close;
_linkMenu.OpenCentered();
_linkMenu = this.CreateWindow<NetworkConfiguratorLinkMenu>();
_linkMenu.OnLinkDefaults += args =>
{
SendMessage(new NetworkConfiguratorLinksSaveMessage(args));
};
_linkMenu.OnToggleLink += (left, right) =>
{
SendMessage(new NetworkConfiguratorToggleLinkMessage(left, right));
};
_linkMenu.OnClearLinks += () =>
{
SendMessage(new NetworkConfiguratorClearLinksMessage());
};
break;
}
}
@@ -83,16 +94,6 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_linkMenu?.Dispose();
_listMenu?.Dispose();
_configurationMenu?.Dispose();
}
private void OnClearButtonPressed()
{
SendMessage(new NetworkConfiguratorClearDevicesMessage());

View File

@@ -9,17 +9,23 @@ namespace Content.Client.NetworkConfigurator;
[GenerateTypedNameReferences]
public sealed partial class NetworkConfiguratorConfigurationMenu : FancyWindow
{
public event Action<string>? OnRemoveAddress;
public NetworkConfiguratorConfigurationMenu()
{
RobustXamlLoader.Load(this);
Clear.StyleClasses.Add(StyleBase.ButtonOpenLeft);
Clear.StyleClasses.Add(StyleNano.StyleClassButtonColorRed);
DeviceList.OnRemoveAddress += args =>
{
OnRemoveAddress?.Invoke(args);
};
}
public void UpdateState(DeviceListUserInterfaceState state)
{
DeviceList.UpdateState(null, state.DeviceList);
DeviceList.UpdateState(state.DeviceList, false);
Count.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count));
}

View File

@@ -7,17 +7,19 @@ namespace Content.Client.NetworkConfigurator;
[GenerateTypedNameReferences]
public sealed partial class NetworkConfiguratorDeviceList : ScrollContainer
{
public void UpdateState(NetworkConfiguratorBoundUserInterface? ui, HashSet<(string address, string name)> devices)
public event Action<string>? OnRemoveAddress;
public void UpdateState(HashSet<(string address, string name)> devices, bool ui)
{
DeviceList.RemoveAllChildren();
foreach (var device in devices)
{
DeviceList.AddChild(BuildDeviceListRow(ui, device));
DeviceList.AddChild(BuildDeviceListRow(device, ui));
}
}
private static BoxContainer BuildDeviceListRow(NetworkConfiguratorBoundUserInterface? ui, (string address, string name) savedDevice)
private BoxContainer BuildDeviceListRow((string address, string name) savedDevice, bool ui)
{
var row = new BoxContainer()
{
@@ -48,10 +50,10 @@ public sealed partial class NetworkConfiguratorDeviceList : ScrollContainer
row.AddChild(name);
row.AddChild(address);
if (ui != null)
if (ui)
{
row.AddChild(removeButton);
removeButton.OnPressed += _ => ui.OnRemoveButtonPressed(savedDevice.address);
removeButton.OnPressed += _ => OnRemoveAddress?.Invoke(savedDevice.address);
}
return row;

View File

@@ -18,20 +18,20 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
private readonly LinksRender _links;
private readonly List<SourcePortPrototype> _sources = new();
private readonly List<SinkPortPrototype> _sinks = new();
private readonly NetworkConfiguratorBoundUserInterface _userInterface;
private (ButtonPosition position, string id, int index)? _selectedButton;
private List<(string left, string right)>? _defaults;
public NetworkConfiguratorLinkMenu(NetworkConfiguratorBoundUserInterface userInterface)
public event Action? OnClearLinks;
public event Action<string, string>? OnToggleLink;
public event Action<List<(string left, string right)>>? OnLinkDefaults;
public NetworkConfiguratorLinkMenu()
{
_userInterface = userInterface;
RobustXamlLoader.Load(this);
var footerStyleBox = new StyleBoxFlat()
@@ -52,7 +52,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
ButtonOk.OnPressed += _ => Close();
ButtonLinkDefault.OnPressed += _ => LinkDefaults();
ButtonClear.OnPressed += _ => _userInterface.SendMessage(new NetworkConfiguratorClearLinksMessage());
ButtonClear.OnPressed += _ => OnClearLinks?.Invoke();
}
public void UpdateState(DeviceLinkUserInterfaceState linkState)
@@ -98,7 +98,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
if (_defaults == default)
return;
_userInterface.SendMessage(new NetworkConfiguratorLinksSaveMessage(_defaults));
OnLinkDefaults?.Invoke(_defaults);
}
private Button CreateButton(ButtonPosition position, string name, string description, string id, int index)
@@ -138,7 +138,7 @@ public sealed partial class NetworkConfiguratorLinkMenu : FancyWindow
var left = _selectedButton.Value.position == ButtonPosition.Left ? _selectedButton.Value.id : id;
var right = _selectedButton.Value.position == ButtonPosition.Left ? id : _selectedButton.Value.id;
_userInterface.SendMessage(new NetworkConfiguratorToggleLinkMessage(left, right));
OnToggleLink?.Invoke(left, right);
args.Button.Pressed = false;

View File

@@ -9,17 +9,20 @@ namespace Content.Client.NetworkConfigurator;
[GenerateTypedNameReferences]
public sealed partial class NetworkConfiguratorListMenu : FancyWindow
{
private readonly NetworkConfiguratorBoundUserInterface _ui;
public NetworkConfiguratorListMenu(NetworkConfiguratorBoundUserInterface ui)
public event Action<string>? OnRemoveAddress;
public NetworkConfiguratorListMenu()
{
RobustXamlLoader.Load(this);
_ui = ui;
DeviceList.OnRemoveAddress += args =>
{
OnRemoveAddress?.Invoke(args);
};
}
public void UpdateState(NetworkConfiguratorUserInterfaceState state)
{
DeviceCountLabel.Text = Loc.GetString("network-configurator-ui-count-label", ("count", state.DeviceList.Count));
DeviceList.UpdateState(_ui, state.DeviceList);
DeviceList.UpdateState(state.DeviceList, true);
}
}

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