Compare commits

..

217 Commits

Author SHA1 Message Date
comasqw
06ca2810c9 Demiplane Crystal 2024-12-17 14:39:37 +04:00
Nim
a248c176ae Crane barrel (#672)
* crane barrel

* fix

* sprite resize, file rename

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
2024-12-16 11:43:29 +03:00
Ed
862df73ff2 Demiplane modifiers groups & tiers (#678)
* data setup

* demiplanes modficators combine refactor

* generationProb

* demiplane tiers setup

* migration, and t2 loots

* t2 balance tweaks

* retags

* weather modifiers group

* maplight modifiers

* more passed checks

* wanderer buy positions localization fix

* fixes
2024-12-16 00:38:29 +03:00
A.Ne.
57a795261f mithril and lucens modular parts (#682)
Co-authored-by: Ed <edwardxperia2000@gmail.com>
2024-12-15 22:40:05 +03:00
Ed
e102b5011e Merge remote-tracking branch 'origin/map-upate' 2024-12-15 22:17:29 +03:00
Viator-MV
35c45e70f6 Christmas map (#681)
* Update comoss.yml

* Update comoss_d.yml
2024-12-15 22:11:38 +03:00
A.Ne.
f655f74b03 mithril and lucens (#660)
* mithril and manarium

* Rename manarium to Lucens

* pointlight to tree

* lucens tile

* Update trees.yml

* logs sprite

* Update trees.yml

* delete acacia tiles, recolor lucen example

* tiles new palette

* Update ores.yml

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

* tiles update

* Update tiles.ftl

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
2024-12-15 12:53:31 +03:00
Ed
58269bb65e Snowballs (#677)
* snowballs

* biome update

* fixes
2024-12-14 14:57:15 +03:00
Ed
d7d0977eb6 New year preparation (#674)
* garland

* presents filter

* vladimirs weather

* snowed tilebrick
2024-12-14 01:01:36 +03:00
Ed
4cea96f6eb Garland (#673)
* garland

* presents filter
2024-12-13 22:20:00 +03:00
Ed
e30c5848c5 Update crates.yml 2024-12-13 17:55:54 +03:00
Ed
c9d2b8fb2b remove footprints (#670) 2024-12-13 17:33:42 +03:00
Ed
e1f67be2a8 Snowdrifts (#669)
* snowdrifts

* Update fire.png

* alerts sprite optimize

* Update wooden.png

* stone wall fix
2024-12-13 16:59:37 +03:00
Ed
3f8757dec9 Update migration.yml 2024-12-13 15:06:10 +03:00
Ed
eb76a9ef6a Ed 12 12 2024 bugfixes (#668)
* fix #665

* fix #664

* fix #661

* fix #666
2024-12-12 23:00:16 +03:00
Ed
93a49ca398 Snowy (#659)
* snow tiles

* snow trees (2\6)

* +1 tree

* third snow layer, and simple snow biome
2024-12-12 21:51:03 +03:00
A.Ne.
2b3cc9e868 key rings fix (#620)
* key rings fix

* Update SharedCP14LockKeySystem.cs
2024-12-12 13:12:58 +03:00
Ed
c42b77d0c9 Merge pull request #658 from crystallpunk-14/ed-11-12-2024-upstream
Upstream sync
2024-12-11 21:18:17 +03:00
Ed
6c8b0a07f3 yep 2024-12-11 21:17:43 +03:00
Ed
af918c1253 Update audio_music.yml 2024-12-11 14:53:49 +03:00
Ed
be15a4097c Update cp14-ignoredPrototypes.yml 2024-12-11 14:49:44 +03:00
Ed
cd736e4fd4 Merge remote-tracking branch 'upstream/stable' into ed-11-12-2024-upstream
# Conflicts:
#	Content.IntegrationTests/Tests/PostMapInitTest.cs
#	Content.Shared/Lock/LockSystem.cs
#	Resources/Maps/oasis.yml
#	Resources/Prototypes/Maps/Pools/default.yml
#	Resources/Prototypes/audio.yml
2024-12-11 14:49:02 +03:00
Ed
576bbe91d0 Roofs (#657)
* simple roo system

* tweaks

* roof sprite update

* transparent roof

* wooden roof sprite

* remove weather: false from all tiles

* stone roof + roofs crafting

* final shtrix, maps update

* fuck

* fix checks

* reagent auto vaporize tweaks

* Update base.yml
2024-12-11 14:44:16 +03:00
Ed
e4b60b31c0 Ed 10 12 2024 aah (#656)
* fix ghost zlevel moving

* stairways autorotation

* ladders sprite update

* slow space swimming

* fix wrong wood spawn

* deadly ocean

* Update zLevels.yml
2024-12-10 21:24:06 +03:00
Ed
99786342fb Comoss sewers (zlevels added) (#655)
* comoss zlevel sewers

* Update biome_template_caves.yml

* Update GhostSystem.cs

* Update GhostSystem.cs
2024-12-10 00:43:30 +03:00
Ed
22b0f46890 Roundleave ship clean up (#653)
* cryo shuttle rework

* Update entities.ftl
2024-12-09 20:39:56 +03:00
Ed
bec8d7a7d4 Ghost z-levels move actions + mapping z-levels combine command (#654)
* some setup

* fast ghost zlevels-moving

* zlevel combine command for mapping
2024-12-09 20:39:46 +03:00
ScarKy0
3844352fee Derelict icon hotfix (#33768)
whoops
2024-12-09 13:56:25 +01:00
Ed
5384adb2b3 Blacksmith again (#652)
* golden and copper sword

* copper sickle

* maces

* shovels

* modular axes

* fixes
2024-12-09 00:40:27 +03:00
Vasilis The Pikachu
8472603b76 Revert "Simplify separated screen top menu (#33047)"
This reverts commit f27fa1ed30.
2024-12-08 21:36:48 +01:00
Ed
c2b7c5146d second blacksmith 2024-12-08 14:43:12 +03:00
Ed
61454e351c Another blacksmith minor update (#648)
* modular golden sickle

* anvil and furnace resprite

* Update comoss.yml
2024-12-08 14:17:48 +03:00
Ed
dc5333ee18 localization update 2024-12-08 01:19:57 +03:00
Ed
0662299120 Aftertest tweaks (#647)
* fix #641

* fix #639

* add copper, bloodflowers and wild sage into comoss island

* remove additional alchemist and blacksmithes roles

* more roundstart resources for alchemist and blacksmith

* disable footprints system

* cryo shuttle mechanic

* update cargo ship

* veryy magical

* tips update

* fix #635

* green cloak

* Update T0_cure_poison.yml
2024-12-08 00:52:35 +03:00
Ed
80be633aa1 Update ContentLocalizationManager.cs 2024-12-07 20:55:30 +03:00
Ed
264ef809bd Update personal_objectives.yml 2024-12-07 20:49:51 +03:00
Ed
ccc97f0e70 Update CP14SandboxRU.xml 2024-12-07 15:04:28 +03:00
Ed
15017b7c4f personal key loadout 2024-12-07 14:49:02 +03:00
Ed
2d54561a31 Update ContentLocalizationManager.cs 2024-12-07 12:41:51 +03:00
Nim
417668b88b Crayon (#634)
* crayon

* add crayon into loots

---------

Co-authored-by: Ed <edwardxperia2000@gmail.com>
2024-12-07 00:50:54 +03:00
Ed
52a0f44aa1 Bank progression mechanic (#633)
* bank progression mechanic

* loc fix

* minor random fixes

* minor tweaks

* lighthouse

* Vladimirs Alerts!

* offset alerts

* lighthouse
2024-12-07 00:39:05 +03:00
deltanedas
3300ff2a06 clean up random lathe recipes (#31525)
Co-authored-by: deltanedas <@deltanedas:kde.org>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2024-12-06 16:45:01 +01:00
MilenVolf
b66fd98514 Localize ai dataset names (#33608)
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2024-12-06 16:38:00 +01:00
K-Dynamic
e244472546 Samurai dogi is now major contraband (#33699) 2024-12-06 16:36:26 +01:00
0tito
de19418126 Add Sprite changes to Logic Gates to show the input/output state (#33277) 2024-12-06 16:35:48 +01:00
beck
6add781c4a Added several variables to make ClumsyComponent more modular for developers. (#33715)
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2024-12-06 16:31:31 +01:00
Ed
02cbeee6dc Demiplane fixes (#632)
* limit demiplace wshwooshing by interaction range, fix global gibbing

* Update base.yml

* fix #521
2024-12-06 17:16:38 +03:00
PJBot
d6d95f1a7a Automatic changelog update 2024-12-06 10:16:30 +00:00
Ed
7d410d6094 Fix debris chunks loot spawning (#33747)
Update DungeonJob.PostGenBiome.cs
2024-12-06 11:15:23 +01:00
Errant
2d6e52b21c vox guidebook update poison regen (#33739)
* vox guidebook regen update

* damage number

* skreee
2024-12-06 09:43:11 +01:00
Southbridge
623a35b3fe Amber Station - Added Evac Shuttle (#33743)
* Added evac shuttle and fixed various issues brought up during playtests

* Updated Amber with playtest feedback, removed waste loop and firelocks from evac shuttle
2024-12-06 01:39:25 -07:00
PJBot
94090f7403 Automatic changelog update 2024-12-06 06:23:45 +00:00
ScarKy0
274c3ab0b9 Derelict Borg Revival (#33433)
* Derelictn'tn't Borg!

* Clean *sparkles*

* Removed "S: Awaiting Changes"
2024-12-06 00:22:38 -06:00
PJBot
38c8ffb9b5 Automatic changelog update 2024-12-06 05:28:59 +00:00
Winkarst
52a886947f Add a maintenance panel to bar signs (#33467)
* Add a maintenance panel to bar signs

* Update Resources/Locale/en-US/wires/wire-names.ftl

* AI interactions

---------

Co-authored-by: Winkarst <74284083+Winkarst-cpu@users.noreply.github.co>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2024-12-05 23:27:52 -06:00
MilenVolf
d6ba7598bd Fix name duplications (#33740)
* Fix name duplication

* Apply requested changes
2024-12-05 23:19:27 -06:00
Velcroboy
207c849e2d Adds Station Anchor Beacon (#33711)
Co-authored-by: Velcroboy <velcroboy333@hotmail.com>
2024-12-05 22:56:34 -06:00
PJBot
cd1177d9ba Automatic changelog update 2024-12-06 04:53:08 +00:00
IProduceWidgets
3e0b93d071 fix a station event weighting bug (#33584)
* fractional weights dont work in StationEvents

* force-int

* sure why not, we can keep floats I guess.
2024-12-05 22:52:02 -06:00
Ed
64df860b50 Salary for the guards (#631)
* public API

* salary init

* salary finish

* Update entities.ftl

* Update salary.yml
2024-12-06 00:59:37 +03:00
PJBot
0e6ec2e1af Automatic changelog update 2024-12-05 21:40:46 +00:00
IProduceWidgets
8f3973b2eb set n2 survival box sprite layers (#33733) 2024-12-05 22:39:39 +01:00
PJBot
97ece026d5 Automatic changelog update 2024-12-05 21:18:37 +00:00
Pieter-Jan Briers
dc8b859916 Give vox health regen for poison below 20 damage (#33722) 2024-12-05 22:17:27 +01:00
Ed
ce34c6f2a0 Update lockTypes.yml 2024-12-05 21:25:34 +03:00
Ed
8252418fdc Update personalHouse.yml 2024-12-05 18:19:10 +03:00
Winkarst
ce672acf91 Fix meteor's ArithmeticException (#33556)
Co-authored-by: Winkarst <74284083+Winkarst-cpu@users.noreply.github.co>
2024-12-05 13:20:27 +01:00
Ed
094fbc445f localization sync 2024-12-05 14:43:43 +03:00
Ed
319cd18ee8 demiplane closing - adventurers tp out and gib (#629) 2024-12-05 12:35:38 +03:00
Leon Friedrich
6f51aa4b15 More device configurator serialization fixes (#33664)
More device configurator invalid entity serialization fixes
2024-12-05 09:36:49 +01:00
Spessmann
59bce41390 Cog vox box removal (#33730)
removed vox box ggggggggggggg
2024-12-04 20:01:56 -07:00
Southbridge
bcf2b9afeb Box Station - Removed Vox Box (#33729)
* Removed vox box and removed nearby fuel tank as well

* made all dirt decals consistent
2024-12-04 19:54:59 -07:00
Emisse
90c8776a60 bagel update (#33726)
* bagel update

* remove invalid

* remove invalid
2024-12-04 19:54:45 -07:00
Southbridge
da68ae94c1 Amber Station - Removed Vox Box (#33725)
Removed Vox Box
2024-12-04 17:02:36 -07:00
Ed
304e1a268a Balance pack (#628)
* map fixes, move crystalls from houses into startgear

* fix lock types

* fix item throwing, reduce lock powers, add lockpick into anvil

* new store positions

* restruct swords

* nerf skeleton, bone halberd
2024-12-05 00:29:14 +03:00
PJBot
fbfcccbe16 Automatic changelog update 2024-12-04 16:51:01 +00:00
keronshb
82528dce37 Adds Store on Collide and Wand of the Locker (#33710)
* Adds wand of locker and locker projectile

* Adds IsOpen method to check if storage is open

* Adds store on collide

* Adds Store On Collide to Wizard Locker

* Adds Lock API

* Adds locking support

* Adds resist override and custom visual layers

* Fixes decursed states, adds comment for a future visualizer

* adds locker wand visuals and descriptions

* shrinks locker radius, moves TODO for throw support

* Adds whitelist and moves storage and lock logic into their own methods

* Adds support to disable store on collide after the first open. Fixes prediction issues with disabling.

* Adds wand of locker to the grimoire

* Adds wizard access prototype

* Adds Wizard to universal access

* Moves Lock on collide to on collide method

* Comments

* Changes layer order

* Fixes prediction issues when locking.

* Adds Wiz access to universal ID
2024-12-04 17:49:54 +01:00
A.Ne.
e6a6900719 Prototypes for Guard (#616)
* Prototypes for Guard

* imperial laws

* merge

* yml clean up

* flags + change in imperial laws

* map update

* guard clothing resprite

* cool guard helmet

* guards grip and halberd

* fill cabinets, add guard commander stamp

* key and keyring fix

* Update arenas.yml

* Update migration.yml

* tapestry fix

* guidebook spacing

* Update meta.json

* add bold tags

* Update flags_wallmount.yml

---------

Co-authored-by: Ed <edwardxperia2000@gmail.com>
2024-12-04 18:11:33 +03:00
Hreno
152cf3388b Add cooldown to buttons in borg's laws UI (#31490) 2024-12-04 21:16:41 +11:00
Tap
2e26ca786d Fix for towels not having a cooldown for cleaning (#33700)
Added a delay to cleaning with the towel
2024-12-04 21:14:59 +11:00
PJBot
fc8f7fb0ba Automatic changelog update 2024-12-04 10:14:29 +00:00
Pieter-Jan Briers
c10a72be39 Fix layout on wires UI (#33714)
Layout would break for machines with >6 lights because the column count was hardcoded. Uncap the UI width and fix the rows count instead.

Lights with less than 4 characters of text weren't aligned right, now they are.
2024-12-04 21:13:22 +11:00
PJBot
7ffd8012f6 Automatic changelog update 2024-12-04 02:43:25 +00:00
Partmedia
cf202e805d Fix sinks and toilets not draining (#33691)
* Fix AutoDrain

Per the system comments, AutoDrain is designed to automatically move
puddles into the drain (like a floor drain). Drains without AutoDrain
are still supposed to gradually empty the buffer, but not remove puddles
(like sinks and toilets).

However, a logic error in the original implementation causes drains with
AutoDrain set to false to simply not work. Hence sinks never emptied.

* Update documentation
2024-12-04 03:42:16 +01:00
Southbridge
87182635b6 Amber Improvements (#33707)
* Various changes (see PR)

* variantized, fixedgridatmos, tiledwalls
2024-12-03 16:59:16 -07:00
Ed
0e88b6dc6f Table fences (#626)
* collision fucks

* map update
2024-12-03 16:21:07 +03:00
Ed
f6630e1ec9 Key distribution system (#625)
* data restruct

* yay

* Update arenas.yml

* fixes

* auto labeling

* shuffle
2024-12-03 12:34:07 +03:00
Southbridge
2c2a435dbd Amber Station Seasonal Update (#33698)
Made some modifications requested by reviewers prior to and after map merge, also added holiday decorations!
2024-12-02 21:58:02 -07:00
PJBot
bfd005a37f Automatic changelog update 2024-12-03 03:00:54 +00:00
CheddaCheez
e50c98c618 Add missing nacho recipes (#33637)
* Nacho recipes, nutrition, and trash

In meal_recipes.yml: Add recipes for Nachos, Cheesy Nachos, and Cuban Nachos.

In meals.yml: Add a solutions container to regular nachos so it lines up with the others, and add a small plate as trash to each one.

* Volumes, nutritional tweaks, and flavor

In meals.yml: Lowered maxVol on nachos to leave 5 units of space. Nachos nutriment and vitamin lowered for costing so little. A cheese wedge is 3.75 nutriment, so cheesy having 4 more total nutritional value lines up nicely to me.

Cuban nachos had too little volume to fit its reagents in the first place, so increased maxVol by 10. Chili peppers are 4 nutri / 4 vitamin and ketchup has a touch of tomato, so bumped to 8 and 5. Capsaicin lowered partly to make it an even 20u. Ketchup dilutes I guess. Also they don't have cheese so I changed the flavor profile to tomato instead.

In meal_recipes.yml: Cuban Nachos recipe tweaked to require one less pepper. Given above numbers, this fits the nutritional value imo.
2024-12-02 20:59:47 -06:00
Luiz Costa
029b0374e9 Juiceable slimeballs (#33660)
adds extractable component to slimeball prototype
2024-12-02 20:51:00 -06:00
Velcroboy
c1491e91b8 Adds a morgue locked maints airlock (#33693)
Co-authored-by: Velcroboy <velcroboy333@hotmail.com>
2024-12-02 20:46:55 -06:00
SpaceRox1244
2e31eb32cb Makes kukri not use combat knife's storage sprite (#33661) 2024-12-02 20:41:42 -06:00
PJBot
f0829a6652 Automatic changelog update 2024-12-03 02:25:45 +00:00
Southbridge
e4e84aea74 New Low-Mid Pop Station - Amber Station (#33441)
* Initial Commit with two departments done

* Checkpointing work

* Added most of service and science

* Started work on medbay

* Modified TEG setup and set up atmos pipes for engineering

* Re-added medbay, added chapel and janitorial, started routing disposals and generally the final layout of the map is coming together

* Plenty of additions, too many to list in a commit message

* Major update

* Nearly done with the map, just have to do decals and emergency lights

* Added all decals, only thing missing is department signs

* Toned back the dirt decals a bunch, added hallway signs and other decorations

* Finishing touches on the map before testing.

* Fixed invalids

* Renamed the station to Amber, and made a couple adjustments

* Completely redid cargo, added maints around sec

* Added Amber to the map post init integration test

* Many small updates addressing issues.

* Ran a script to update all the camera names, also ran fixgridatmos, fixrotations, tilewalls, and variantize

* Started addressing some of the issues brough up by Emisse and others

* Addressed all issues mentioned by reviewers. Added mail system.

* Wrapped up meeting all the issues raised by reviewers, also did a bunch of testing and resolved issues found during those tests

* Addressed additional requested changes, and nabbed some ship designs from Frontier. Redesigned south east maints and surrounding meteor nets based off of those designs

* Making a couple more requested changes

* Reduced the amount of Nitrogen Closets, made several small adjustments. Ready for review again!

* Removed invalids!

* web edit lmao

---------

Co-authored-by: Emisse <99158783+Emisse@users.noreply.github.com>
2024-12-02 19:24:37 -07:00
SpaceManiac
b800d98260 Fix lobby countdown not showing hours (#33685) 2024-12-02 13:29:44 -08:00
PJBot
cc804bf316 Automatic changelog update 2024-12-02 19:45:08 +00:00
JIPDawg
638a1dc489 Fixed ghost role rules for some syndicate familiars (#32457)
* fix ghost role rules for some syndicate familiars

* change from monkey rules to Team Antag rules.

* Resolve reviews + Fix rules for LoneOp and Xenos

* ghostrole rules

---------

Co-authored-by: JIPDawg <JIPDawg93@gmail.com>
Co-authored-by: Errant <35878406+Errant-4@users.noreply.github.com>
2024-12-02 20:43:59 +01:00
dylanstrategie
7f966ab9b1 Touching up Bagel Security Brig (#33680)
* Touching up Bagel Security Brig

* Added a few missing door names

* Last door name I promise

* Address feedback

* Forgot to delete old shutter button

---------

Co-authored-by: dylanstrategie <188926747+dylanstrategie@users.noreply.github.com~>
2024-12-02 04:29:45 -07:00
PJBot
560fd8dd77 Automatic changelog update 2024-12-01 22:10:41 +00:00
MilenVolf
b3841e8414 Fix BuckleSystem always marking InteractHandEvent as Handled (#33602)
* Add check before marking event as handled

* Update Content.Shared/Buckle/SharedBuckleSystem.Interaction.cs

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>

* Cleanup

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2024-12-01 23:09:34 +01:00
Ed
7e6e4709c4 Ed 01 12 2024 rapier (#623)
* Rapier blade

* file restruct

* golden garde

* iron sharp garde

* copper garde
2024-12-02 00:08:23 +03:00
MilenVolf
d4067bcaab Fix wrong system usage (#33679)
Fix wrong system using
2024-12-01 11:34:18 -08:00
Ed
c6ac192dfb Gold & Copper modular parts 1 (#621)
* gold & copper daggers

* copper and gold short grip

* gold & copper grips

* golden pickaxe

* copper pickaxe

* Update anvil.yml
2024-12-01 20:11:59 +03:00
PJBot
237324e268 Automatic changelog update 2024-12-01 06:31:13 +00:00
IProduceWidgets
bf312f2306 Update Snowasis (#33364)
* Update Snowasis

* Appease test gods

* Woops had the leftward animation backwards. Fixed.

* add santa suits and envelopes to chapel

* It looks worse unscaled but whatever.

* fix ghost role

* examines
2024-11-30 23:30:01 -07:00
MilenVolf
5fdf03c216 Replace obsolete GetTilesIntersecting methods (#32455)
* Remove usage of obsolete GetTilesIntersecting round 1

* Oop wrong uids

* Remove usage of obsolete GetLocalTilesIntersecting round 2

* Remove usage of obsolete GetLocalTilesIntersecting final round

* weh

* Fix using `SharedMapSystem` in `StencilOverlay`
2024-12-01 12:56:47 +11:00
Nikolai Korolev
2d405c9652 Fix formatting IDE0055 warnings in VS Code (#33669) 2024-12-01 12:51:26 +11:00
github-actions[bot]
3984f0aa0a Update Credits (#33670)
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
2024-12-01 12:51:12 +11:00
PJBot
a46323d9f9 Automatic changelog update 2024-11-30 20:12:50 +00:00
Token
061b1b8adb Fix makeghostroleraffle command where 4 arguments (#31836)
Fix makeghostroleraffle command with 4 arguments
2024-11-30 21:11:44 +01:00
PJBot
44ef60a642 Automatic changelog update 2024-11-30 19:32:46 +00:00
Preston Smith
efb35d7953 Require Wield To Activate Double-bladed ESword (#32869)
* Add MeleeRequiresWield component

* Prevent world activation
2024-11-30 20:31:40 +01:00
PJBot
720fccf3f3 Automatic changelog update 2024-11-30 17:26:15 +00:00
Winkarst
ab36b15080 Fix borgs not getting names on roundstart (#33578)
* Fix borgs not getting names on roundstart

* Glory to the NT

* Allow riggable to take in multiple reagents

* Revert

---------

Co-authored-by: Winkarst <74284083+Winkarst-cpu@users.noreply.github.co>
2024-11-30 18:25:09 +01:00
PJBot
766389a66b Automatic changelog update 2024-11-30 16:24:33 +00:00
Plykiya
fb76cd952e Fix for inspecting entities in the stripping window (#33644)
Handle it
2024-11-30 17:23:26 +01:00
PJBot
3d984603f1 Automatic changelog update 2024-11-30 16:15:45 +00:00
Plykiya
450bf813b8 Fix for inspecting entities in hand (#33642)
Actually inspect entity in hands
2024-11-30 17:14:39 +01:00
PJBot
973f42b3b2 Automatic changelog update 2024-11-30 16:00:03 +00:00
Plykiya
021c9832ef Fix for handcuffing someone more than once (#33646)
* Fix for over-cuffing someone

* comment
2024-11-30 16:58:56 +01:00
Ed
bb43b37fd8 Bugfixes (#619)
* clean up

* Update empire_orders.yml
2024-11-30 14:16:48 +03:00
PJBot
86791583f9 Automatic changelog update 2024-11-30 06:24:58 +00:00
compilatron
08db47cb28 Cog/Marathon: Airlock fixes (#33621)
* Fixes the TEG airlock on marathon

* Fixes the atmos external airlock on cog
2024-11-29 23:23:50 -07:00
lunarcomets
b45c9d5129 fix PermanentBlindnessComponent to be not so permanent (#33292)
* adjust min blindness back to 0 when PermanentBlindnessComponent is removed

* mapinit changes

* remove OnRemove, move changes to OnShutdown

* goodbye event

* dependency removal

* final adjustment

---------

Co-authored-by: lunarcomets <luanrcomets2@gmail,com>
2024-11-30 13:56:52 +11:00
PJBot
e9ef00f475 Automatic changelog update 2024-11-30 02:55:44 +00:00
VideoKompany
54a9dce68d add locale to Shuttle Console Map tab (#33651)
fixed
2024-11-30 13:54:37 +11:00
PJBot
17a224c86a Automatic changelog update 2024-11-30 02:49:12 +00:00
Gansu
9236e9e5b9 Fix for arrivals deleting nuke (#33659)
Adds FTLSmashImmune to nuke prototype to stop it from arrival smashing
Adds a comment in FasterThanLight to indicate where the FTLSmashImmuneComponent is checked

Co-authored-by: aa5g21 <aa5g21@soton.ac.uk>
2024-11-30 13:48:04 +11:00
MilenVolf
6c86d7b32b Cleanup some Client atmos systems (#33634)
* Cleanup `ScrubberControl.xaml.cs`

* Minor cleanups

* Another pile of minor cleanups

* Apply requested changes

* Rename "which" into "bound". Add whitespace after "if"
2024-11-30 02:33:29 +01:00
Ed
373d3a892b New Comoss island map (#618)
* Create island_new.yml

* first map state
2024-11-30 01:08:44 +03:00
PJBot
f99331aa00 Automatic changelog update 2024-11-29 12:52:21 +00:00
MossyGreySlope
87d6b0b79b Rename nitrogen internals crate (#33545)
* rename nitrogen internals crate

* nitrogen internals crate description

* migrate CrateNitrogenInternals ID
2024-11-29 13:51:15 +01:00
PJBot
bbdadd7144 Automatic changelog update 2024-11-29 09:47:31 +00:00
DrSmugleaf
3ad227a904 Add admin log for ghost warping (#33636) 2024-11-29 10:46:24 +01:00
Myra
422d1a9d32 Remove grasshopper from the panic bunker message (#33638)
Can be retargetted to stable if preferred, which will then be a hotfix
2024-11-29 20:27:14 +11:00
PJBot
2e340578ff Automatic changelog update 2024-11-29 08:15:22 +00:00
Alice "Arimah" Heurlin
360f6982f4 Display GPS coordinates on their own line (#33625) 2024-11-29 11:14:14 +03:00
Alpha-Two
93bdd813c4 Fix gender, maybe (#33631)
Co-authored-by: Alpha-Two <alpha2.5232@gmail.com>
2024-11-29 08:54:46 +01:00
Ed
109edeb4b5 Modular weapon crafting WIP (#611)
* data initalizing

* modular assembling

* grips and blades sprites

* first prototypes

* jewerly decoration

* disassemble modular weapon

* grip start stats

* blade modifiers

* inhand sprites generation

* resprites inhand, add sickle, add attempt modify size

* auto inhand sprite parsing

* icon default parsing

* spear blade

* mace ball

* sword blade

* sharedization + autonetwork hotswipe

* wielding sprite support!

* iron long grip

* wielded sickle, fix ERROR sprite if state not added

* Update grips.yml

* wielded spear + ruby rework

* wielding damage bonus modifier

* modular size fix

* fix storedOffset rotation

* parts offset

* fix inheriting modifiers

* some bugfix and balance tweaks

* DPS Meter

* fix dividing by zero

* rebalance

* replace baseknife to modular knife. Delete ice knife spell

* sickle and mace modular replace

* modular spear & sword replacement. add wielded icons

* Update CP14DPSMeterSystem.cs

* back to serverization

* grip disassemble drop again

* clothing sprite generation code

* back slot long grips and mace

* remove jewerly slot, add more clothing states

* finish clothing states

* shovel modular

* YEEEEE

* anvil modular craft

* bugfixes

* more integration check fixes
2024-11-29 01:31:42 +03:00
Myra
b53c8ea60e Approval labeler fix electric boogaloo (#33633)
Nik told me to not name this "nya"
2024-11-28 21:54:01 +01:00
Nikolai Korolev
4a21ed87db Update Content.PatreonParser to use net8.0 TargetFramework (#33559)
Update Content.PatreonParse to use net8.0 targetframework
2024-11-28 20:13:26 +01:00
PJBot
6463e7e08e Automatic changelog update 2024-11-28 13:42:10 +00:00
beck-thompson
a790955b76 Light verb is now predicted (#33622)
Fix
2024-11-29 00:41:01 +11:00
SpaceRox1244
f6813e39c7 Makes knives fly straight when thrown (#33615)
Gives knives a thrown angle
2024-11-28 16:09:47 +03:00
SpaceManiac
a206acc220 Fix swapped uniform printer east/west sprites (#33442)
Fix uniform printer sprites rotating the wrong way
2024-11-28 21:38:33 +11:00
Mifia
de613e45f8 Fix gauze eyepatch flying pixel (#33564)
boo
2024-11-28 21:34:43 +11:00
AlexUm
ac65c5a55d Fix version for electril_grill meta.json (#33611)
fix

fixing the version thing in meta json for electril grill textures

Co-authored-by: Arthur Kustenko <arthur.kustenko@learnet.se>
2024-11-28 21:30:13 +11:00
ScarKy0
9704ed7a00 Added Oppenhopper poster to the game. (#33588)
* o7

* -

* oppenhopper v2

* Update Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml

* Update Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2024-11-28 11:08:43 +01:00
Flareguy
56fd7cbb6f Removes burnt tiles (#33422)
remove burnt tiles
2024-11-28 09:49:41 +03:00
Myra
1bc65624c8 Merge stable into master: Hotfix the randomly occurring DeleteAllThenGhost test failures (#33593) 2024-11-27 09:05:31 +00:00
PJBot
1b6c9e866b Automatic changelog update 2024-11-27 05:56:21 +00:00
slarticodefast
8ea388b309 Fix windoor and high security door not showing electrocution HUD (#33551) 2024-11-27 16:55:14 +11:00
PJBot
6187675c27 Automatic changelog update 2024-11-27 05:33:46 +00:00
slarticodefast
c861c56a69 Fix space ambient music (#33594) 2024-11-27 16:32:39 +11:00
Errant
eb9540364e Hotfix the randomly occurring DeleteAllThenGhost test failures (#33582)
* clear mindrole on component shutdown

* let it go
2024-11-27 00:56:35 +01:00
dylanstrategie
ab7221efad Added two N2 lockers to Reach (#33409)
Co-authored-by: dylanstrategie <188926747+dylanstrategie@users.noreply.github.com~>
2024-11-26 13:04:34 -07:00
PJBot
dfc3562bfc Automatic changelog update 2024-11-26 13:51:29 +00:00
Winkarst
41d2cf166d Make shuttle airlocks not snapcardinals (#33557)
* Make shuttle airlocks not snapcardinals

* Update Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>

* Update Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>

---------

Co-authored-by: Winkarst <74284083+Winkarst-cpu@users.noreply.github.co>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2024-11-27 00:51:13 +11:00
slarticodefast
470c869ce2 Greytide Virus station event (#33547)
* proof of concept

* full implementation

* I commited a crime

* t

* min players increase
2024-11-27 00:50:20 +11:00
Intoxicating-Innocence
d5225d1f46 Ghost role drop-down alignment (#33397)
* dropdown shares margin width with children

* removed dependency that rider added for some reason

* reduced vertical margin from 8 to 2
2024-11-26 09:28:31 +01:00
PJBot
a69fc39fc0 Automatic changelog update 2024-11-26 01:00:41 +00:00
metalgearsloth
f27fa1ed30 Simplify separated screen top menu (#33047) 2024-11-26 01:59:34 +01:00
slarticodefast
e9eca826d8 minor AI cleanup (#33555)
* minor cleanup

* to
2024-11-26 09:39:04 +11:00
Vasilis
f0e9de8489 "Borgimorph" Release 2024-11-22 (#33544) 2024-11-25 15:25:04 +00:00
Flareguy
b8c8f7d0f8 Adds more diona names (#33066)
* adds more diona names

* more stuff

* AHHHHHHHHHHHHHHHHHHHHHHH

* further additions

* removes depression + adds comment

* fixes + remove some weird stuff + more stuff

* remove haste
2024-11-25 14:51:41 +01:00
PJBot
b8466d8321 Automatic changelog update 2024-11-25 12:36:20 +00:00
Niels Huylebroeck
49724a9b9d Turn off PointLights on VendingMachines when broken or off. (#33513)
The light itself should already turn off due to `LitOnPowered`
component, but the broken state of a VendingMachine did not.

Fixes  #33382
2024-11-25 13:35:14 +01:00
PJBot
ae576abe1f Automatic changelog update 2024-11-25 12:25:04 +00:00
Minemoder5000
45cf4ec340 Shark plushies now goes rawr on hit. (#33540)
Shark goes rawr more
2024-11-25 13:23:57 +01:00
Nikolai Korolev
ea7f5433ac Fix RA0003 warning for ChatBox (#33531) 2024-11-25 22:53:12 +11:00
Ben
32f48d974f removed obsolete netmessage creator (#33542)
removed opsolete netmessage createor
2024-11-25 22:39:10 +11:00
Errant
14103e7a86 Hotfix babyproof arrivals terminal and arrivals shuttle (#33538) 2024-11-25 12:12:11 +01:00
PJBot
da9b2e6a10 Automatic changelog update 2024-11-25 07:21:39 +00:00
Schrödinger
f53e3ec3c1 [BUGFIX] "Ghost" in the lobby lets you see the whole chat (#33529)
* fix bug, in ghost command lobby

* fix

* Fix build
2024-11-25 10:20:31 +03:00
IProduceWidgets
9a898bb98e babyproof arrivals shuttle (#33284)
* babyproof arrivals shuttle

* always powered lights

* uncuttable cables from terminal PR.

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2024-11-25 07:59:37 +01:00
IProduceWidgets
86a3d1636f baby proof the terminal (#33281)
* baby proof the terminal

* Make a couple exceptions for items that you might take with you.

* alwayspoweredlights

* Uncuttable cables since cablecomp is a snowflake construction system

* chairs and vendors

* rerun heisentests

* rerun tests again
2024-11-25 07:59:01 +01:00
PJBot
ed2cd23309 Automatic changelog update 2024-11-25 04:28:02 +00:00
slarticodefast
3c6c5ab6c9 fix airlocks inconsistently auto-closing after unbolting (#33524)
fix door auto close timer
2024-11-25 15:26:54 +11:00
kosticia
d642ee7707 Delete HOS headset from warden's locker (#33234)
* add headset

* Add icons

* Meta change

* fix

* Revert + delete headset from locker
2024-11-25 01:46:33 +01:00
mubururu_
cae49ae0d2 various material & ore inhands (#33342)
* begin

* bones + pyrotten + goliath hide inhands

* Update Resources/Prototypes/Entities/Objects/Materials/materials.yml

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>

* Update Resources/Textures/Objects/Materials/materials.rsi/meta.json

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>

* Update Resources/Textures/Objects/Materials/materials.rsi/meta.json

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>

* Update Resources/Textures/Objects/Materials/materials.rsi/meta.json

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>

* pyrottOn

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2024-11-24 17:24:13 +01:00
PJBot
91b9d4a7f0 Automatic changelog update 2024-11-24 08:50:37 +00:00
deltanedas
e436a50c36 fix exped caves generation (#32890)
Co-authored-by: deltanedas <@deltanedas:kde.org>
2024-11-24 09:49:31 +01:00
PJBot
84df2b857e Automatic changelog update 2024-11-24 08:12:54 +00:00
MilenVolf
aa80a88cc4 Allow shuttles on planets to make FTL jump (#33507)
This check conflicts with an attempt to FTL from the planet before expedition ends
2024-11-24 11:11:47 +03:00
PJBot
2229a6a04b Automatic changelog update 2024-11-24 04:21:08 +00:00
Winkarst
f706170ee1 Draw muzzle flash below mobs (#33465)
* Draw muzzle flash below mobs

* Better naming

---------

Co-authored-by: Winkarst <74284083+Winkarst-cpu@users.noreply.github.co>
2024-11-24 15:20:00 +11:00
github-actions[bot]
ef89d5cc21 Update Credits (#33503)
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
2024-11-24 12:56:18 +11:00
PJBot
e958c0c9b0 Automatic changelog update 2024-11-23 16:54:04 +00:00
metalgearsloth
11dbf50ed6 Add delay to AutoOrient (#33479)
It functions identically to how V1 of orientation worked and it's incredibly annoying.
2024-11-23 17:52:58 +01:00
PJBot
8522ffe8ce Automatic changelog update 2024-11-23 15:15:19 +00:00
IProduceWidgets
fab9993a3b babyproof arrivals shuttle (#33284)
* babyproof arrivals shuttle

* always powered lights

* uncuttable cables from terminal PR.

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
2024-11-23 16:14:13 +01:00
PJBot
4cecf99e65 Automatic changelog update 2024-11-23 11:42:43 +00:00
goet
855547a2d4 Ensure wires can always be cut (#32447)
ensure wires are always cut
2024-11-23 12:41:37 +01:00
PJBot
45af6a13fc Automatic changelog update 2024-11-23 11:21:05 +00:00
metalgearsloth
11dae2ff93 Don't show drag-drop outline if climbing (#33477)
It won't actually do anything.
2024-11-23 12:19:59 +01:00
PJBot
bde85858a3 Automatic changelog update 2024-11-23 09:32:14 +00:00
metalgearsloth
c3786a56dc Fix door animations mispredicting if closing is interrupted (#33481)
* Fix door animations mispredicting if closing is interrupted

On master it will flicker states a little bit partially due to it not being predicted.

Instead we'll just set it straight back to opening (no animation is ever played anyway).

* no log
2024-11-23 10:31:07 +01:00
eoineoineoin
bdf4a46edf Minor improvements & fixes to Shuttle Console UI (#31623)
* Fix grids and docks being culled from display prematurely

* Fix inconsistent disabling of "Undock" buttons

* Add a radar icon to indicate where the controlling console is

* Tidy up math

Remove lots of sketchy transforms-of-transforms, which should have been
as single matrix multiply. Assign proper names to matrices. Remove some
redundant calculations.

* Feedback
2024-11-23 17:55:09 +11:00
MetalSage
a42bacd3a9 Fix startingGear storage (#33394)
* fix starting gear storage

* removal of unused

---------

Co-authored-by: MetalSage <metalsage.official@gmail.com>
2024-11-23 17:54:35 +11:00
PJBot
1e93e12330 Automatic changelog update 2024-11-23 06:42:34 +00:00
Winkarst
0a587c9ccc Disable submit admin note button on switch to note (#33456)
Co-authored-by: Winkarst <74284083+Winkarst-cpu@users.noreply.github.co>
2024-11-23 17:41:28 +11:00
PJBot
7feafcbe95 Automatic changelog update 2024-11-23 06:38:21 +00:00
metalgearsloth
5409815be9 Allow AI and observers to see electrified doors (#33466) 2024-11-23 17:37:14 +11:00
PJBot
d8ecf12fca Automatic changelog update 2024-11-23 02:54:55 +00:00
metalgearsloth
616907009d Fix salvage vendor inventory (#33437) 2024-11-23 13:53:47 +11:00
PJBot
6bc205484f Automatic changelog update 2024-11-22 22:51:50 +00:00
IProduceWidgets
a28adf4ae4 baby proof the terminal (#33281)
* baby proof the terminal

* Make a couple exceptions for items that you might take with you.

* alwayspoweredlights

* Uncuttable cables since cablecomp is a snowflake construction system

* chairs and vendors

* rerun heisentests

* rerun tests again
2024-11-22 23:50:41 +01:00
slarticodefast
de516905f0 another rename 2024-11-22 23:39:05 +01:00
slarticodefast
306277afe0 rename 2024-11-22 23:05:36 +01:00
slarticodefast
08bfb43feb cleanup 2024-11-22 23:02:59 +01:00
slarticodefast
5a9a2d463b Merge branch 'master' into powerhud 2024-11-22 19:38:55 +01:00
slarticodefast
3758715bdc electrification hud 2024-11-22 00:43:02 +01:00
MissKay1994
c02a027cf1 Update salvage.yml 2024-11-20 18:06:19 -05:00
MissKay1994
e96e80bc95 Update salvage.yml 2024-11-20 18:05:01 -05:00
MissKay1994
f23b6522b2 Update cargo_vending.yml 2024-11-20 04:44:33 -05:00
MissKay1994
693e5f1fad Update salvage.yml 2024-11-20 03:40:54 -05:00
1439 changed files with 329671 additions and 14718 deletions

View File

@@ -16,7 +16,7 @@ jobs:
with:
username: ${{ github.actor }}
team: "content-maintainers,junior-maintainers"
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
GITHUB_TOKEN: ${{ secrets.LABELER_PAT }}
- if: ${{ steps.checkUserMember.outputs.isTeamMember == 'true' }}
uses: actions-ecosystem/action-add-labels@v1
with:

View File

@@ -258,13 +258,13 @@ namespace Content.Client.Actions
public void LinkAllActions(ActionsComponent? actions = null)
{
if (_playerManager.LocalEntity is not { } user ||
!Resolve(user, ref actions, false))
{
return;
}
if (_playerManager.LocalEntity is not { } user ||
!Resolve(user, ref actions, false))
{
return;
}
LinkActions?.Invoke(actions);
LinkActions?.Invoke(actions);
}
public override void Shutdown()

View File

@@ -159,6 +159,7 @@ public sealed partial class NoteEdit : FancyWindow
SecretCheckBox.Pressed = false;
SeverityOption.Disabled = false;
PermanentCheckBox.Pressed = true;
SubmitButton.Disabled = true;
UpdatePermanentCheckboxFields();
break;
case (int) NoteType.Message: // Message: these are shown to the player when they log on

View File

@@ -1,8 +1,4 @@
using Robust.Shared.GameObjects;
namespace Content.Client.Atmos.Components;
[RegisterComponent]
public sealed partial class PipeColorVisualsComponent : Component
{
}
public sealed partial class PipeColorVisualsComponent : Component;

View File

@@ -1,6 +1,5 @@
<BoxContainer xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:Content.Client.Stylesheets"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Orientation="Vertical" HorizontalExpand ="True" Margin="0 0 0 3">
@@ -62,7 +61,7 @@
</PanelContainer>
</BoxContainer>
<!-- If the alarm is inactive, this is label is diplayed instead -->
<!-- If the alarm is inactive, this is label is displayed instead -->
<Label Name="NoDataLabel" Text="{Loc 'atmos-alerts-window-no-data-available'}" HorizontalAlignment="Center" Margin="0 15" FontColorOverride="#a9a9a9" ReservesSpace="False" Visible="False"></Label>
<!-- Silencing progress bar -->

View File

@@ -136,8 +136,9 @@ public sealed partial class AtmosAlarmEntryContainer : BoxContainer
GasGridContainer.RemoveAllChildren();
var gasData = focusData.Value.GasData.Where(g => g.Key != Gas.Oxygen);
var keyValuePairs = gasData.ToList();
if (gasData.Count() == 0)
if (keyValuePairs.Count == 0)
{
// No other gases
var gasLabel = new Label()
@@ -158,13 +159,11 @@ public sealed partial class AtmosAlarmEntryContainer : BoxContainer
else
{
// Add an entry for each gas
foreach ((var gas, (var mol, var percent, var alert)) in gasData)
foreach ((var gas, (var mol, var percent, var alert)) in keyValuePairs)
{
var gasPercent = (FixedPoint2)0f;
gasPercent = percent * 100f;
FixedPoint2 gasPercent = percent * 100f;
if (!_gasShorthands.TryGetValue(gas, out var gasShorthand))
gasShorthand = "X";
var gasShorthand = _gasShorthands.GetValueOrDefault(gas, "X");
var gasLabel = new Label()
{

View File

@@ -14,8 +14,6 @@ public sealed class AtmosAlertsComputerBoundUserInterface : BoundUserInterface
_menu = new AtmosAlertsComputerWindow(this, Owner);
_menu.OpenCentered();
_menu.OnClose += Close;
EntMan.TryGetComponent<TransformComponent>(Owner, out var xform);
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -24,9 +22,6 @@ public sealed class AtmosAlertsComputerBoundUserInterface : BoundUserInterface
var castState = (AtmosAlertsComputerBoundInterfaceState) state;
if (castState == null)
return;
EntMan.TryGetComponent<TransformComponent>(Owner, out var xform);
_menu?.UpdateUI(xform?.Coordinates, castState.AirAlarms, castState.FireAlarms, castState.FocusData);
}

View File

@@ -1,7 +1,6 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.Pinpointer.UI"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
Title="{Loc 'atmos-alerts-window-title'}"
Resizable="False"
SetSize="1120 750"

View File

@@ -4,8 +4,6 @@ using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.Piping;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.ResourceManagement;
using Robust.Shared.Serialization.TypeSerializers.Implementations;
namespace Content.Client.Atmos.EntitySystems;
@@ -19,7 +17,7 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem
base.Initialize();
SubscribeLocalEvent<PipeAppearanceComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<PipeAppearanceComponent, AppearanceChangeEvent>(OnAppearanceChanged, after: new[] { typeof(SubFloorHideSystem) });
SubscribeLocalEvent<PipeAppearanceComponent, AppearanceChangeEvent>(OnAppearanceChanged, after: [typeof(SubFloorHideSystem)]);
}
private void OnInit(EntityUid uid, PipeAppearanceComponent component, ComponentInit args)
@@ -84,7 +82,8 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem
layer.Visible &= visible;
if (!visible) continue;
if (!visible)
continue;
layer.Color = color;
}

View File

@@ -1,12 +1,7 @@
using System.Collections.Generic;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Power;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.Atmos.Monitor;
@@ -27,7 +22,7 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem<AtmosAlarmabl
{
foreach (var visLayer in component.HideOnDepowered)
{
if (args.Sprite.LayerMapTryGet(visLayer, out int powerVisibilityLayer))
if (args.Sprite.LayerMapTryGet(visLayer, out var powerVisibilityLayer))
args.Sprite.LayerSetVisible(powerVisibilityLayer, powered);
}
}
@@ -36,7 +31,7 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem<AtmosAlarmabl
{
foreach (var (setLayer, powerState) in component.SetOnDepowered)
{
if (args.Sprite.LayerMapTryGet(setLayer, out int setStateLayer))
if (args.Sprite.LayerMapTryGet(setLayer, out var setStateLayer))
args.Sprite.LayerSetState(setStateLayer, new RSI.StateId(powerState));
}
}

View File

@@ -1,11 +1,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;
namespace Content.Client.Atmos.Monitor.UI;
@@ -78,6 +74,7 @@ public sealed class AirAlarmBoundUserInterface : BoundUserInterface
{
base.Dispose(disposing);
if (disposing) _window?.Dispose();
if (disposing)
_window?.Dispose();
}
}

View File

@@ -8,7 +8,6 @@ using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.Temperature;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
@@ -59,7 +58,7 @@ public sealed partial class AirAlarmWindow : FancyWindow
AirAlarmMode.Fill => "air-alarm-ui-mode-fill",
AirAlarmMode.Panic => "air-alarm-ui-mode-panic",
AirAlarmMode.None => "air-alarm-ui-mode-none",
_ => "error"
_ => "error",
};
_modes.AddItem(Loc.GetString(text));
}
@@ -70,7 +69,7 @@ public sealed partial class AirAlarmWindow : FancyWindow
AirAlarmModeChanged!.Invoke((AirAlarmMode) args.Id);
};
_autoMode.OnToggled += args =>
_autoMode.OnToggled += _ =>
{
AutoModeChanged!.Invoke(_autoMode.Pressed);
};
@@ -176,22 +175,18 @@ public sealed partial class AirAlarmWindow : FancyWindow
public static Color ColorForThreshold(float amount, AtmosAlarmThreshold threshold)
{
threshold.CheckThreshold(amount, out AtmosAlarmType curAlarm);
threshold.CheckThreshold(amount, out var curAlarm);
return ColorForAlarm(curAlarm);
}
public static Color ColorForAlarm(AtmosAlarmType curAlarm)
{
if(curAlarm == AtmosAlarmType.Danger)
return curAlarm switch
{
return StyleNano.DangerousRedFore;
}
else if(curAlarm == AtmosAlarmType.Warning)
{
return StyleNano.ConcerningOrangeFore;
}
return StyleNano.GoodGreenFore;
AtmosAlarmType.Danger => StyleNano.DangerousRedFore,
AtmosAlarmType.Warning => StyleNano.ConcerningOrangeFore,
_ => StyleNano.GoodGreenFore,
};
}

View File

@@ -1,12 +1,8 @@
using System;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Localization;
namespace Content.Client.Atmos.Monitor.UI.Widgets;
@@ -25,7 +21,7 @@ public sealed partial class PumpControl : BoxContainer
private OptionButton _pressureCheck => CPressureCheck;
private FloatSpinBox _externalBound => CExternalBound;
private FloatSpinBox _internalBound => CInternalBound;
private Button _copySettings => CCopySettings;
private Button _copySettings => CCopySettings;
public PumpControl(GasVentPumpData data, string address)
{
@@ -86,7 +82,7 @@ public sealed partial class PumpControl : BoxContainer
_data.PressureChecks = (VentPressureBound) args.Id;
PumpDataChanged?.Invoke(_address, _data);
};
_copySettings.OnPressed += _ =>
{
PumpDataCopied?.Invoke(_data);

View File

@@ -1,15 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Localization;
namespace Content.Client.Atmos.Monitor.UI.Widgets;
@@ -27,7 +21,7 @@ public sealed partial class ScrubberControl : BoxContainer
private OptionButton _pumpDirection => CPumpDirection;
private FloatSpinBox _volumeRate => CVolumeRate;
private CheckBox _wideNet => CWideNet;
private Button _copySettings => CCopySettings;
private Button _copySettings => CCopySettings;
private GridContainer _gases => CGasContainer;
private Dictionary<Gas, Button> _gasControls = new();
@@ -77,7 +71,7 @@ public sealed partial class ScrubberControl : BoxContainer
_data.PumpDirection = (ScrubberPumpDirection) args.Id;
ScrubberDataChanged?.Invoke(_address, _data);
};
_copySettings.OnPressed += _ =>
{
ScrubberDataCopied?.Invoke(_data);

View File

@@ -43,7 +43,8 @@ public sealed partial class SensorInfo : BoxContainer
var label = new RichTextLabel();
var fractionGas = amount / data.TotalMoles;
label.SetMarkup(Loc.GetString("air-alarm-ui-gases-indicator", ("gas", $"{gas}"),
label.SetMarkup(Loc.GetString("air-alarm-ui-gases-indicator",
("gas", $"{gas}"),
("color", AirAlarmWindow.ColorForThreshold(fractionGas, data.GasThresholds[gas])),
("amount", $"{amount:0.####}"),
("percentage", $"{(100 * fractionGas):0.##}")));
@@ -53,9 +54,9 @@ public sealed partial class SensorInfo : BoxContainer
var threshold = data.GasThresholds[gas];
var gasThresholdControl = new ThresholdControl(Loc.GetString($"air-alarm-ui-thresholds-gas-title", ("gas", $"{gas}")), threshold, AtmosMonitorThresholdType.Gas, gas, 100);
gasThresholdControl.Margin = new Thickness(20, 2, 2, 2);
gasThresholdControl.ThresholdDataChanged += (type, threshold, arg3) =>
gasThresholdControl.ThresholdDataChanged += (type, alarmThreshold, arg3) =>
{
OnThresholdUpdate!(_address, type, threshold, arg3);
OnThresholdUpdate!(_address, type, alarmThreshold, arg3);
};
_gasThresholds.Add(gas, gasThresholdControl);
@@ -64,7 +65,8 @@ public sealed partial class SensorInfo : BoxContainer
_pressureThreshold = new ThresholdControl(Loc.GetString("air-alarm-ui-thresholds-pressure-title"), data.PressureThreshold, AtmosMonitorThresholdType.Pressure);
PressureThresholdContainer.AddChild(_pressureThreshold);
_temperatureThreshold = new ThresholdControl(Loc.GetString("air-alarm-ui-thresholds-temperature-title"), data.TemperatureThreshold,
_temperatureThreshold = new ThresholdControl(Loc.GetString("air-alarm-ui-thresholds-temperature-title"),
data.TemperatureThreshold,
AtmosMonitorThresholdType.Temperature);
TemperatureThresholdContainer.AddChild(_temperatureThreshold);
@@ -103,7 +105,8 @@ public sealed partial class SensorInfo : BoxContainer
}
var fractionGas = amount / data.TotalMoles;
label.SetMarkup(Loc.GetString("air-alarm-ui-gases-indicator", ("gas", $"{gas}"),
label.SetMarkup(Loc.GetString("air-alarm-ui-gases-indicator",
("gas", $"{gas}"),
("color", AirAlarmWindow.ColorForThreshold(fractionGas, data.GasThresholds[gas])),
("amount", $"{amount:0.####}"),
("percentage", $"{(100 * fractionGas):0.##}")));

View File

@@ -1,7 +1,4 @@
using Content.Client.Message;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Temperature;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;

View File

@@ -1,12 +1,8 @@
using System;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Monitor.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Localization;
// holy FUCK
// this technically works because some of this you can *not* do in XAML but holy FUCK
@@ -115,29 +111,38 @@ public sealed partial class ThresholdControl : BoxContainer
_enabled.Pressed = !_threshold.Ignore;
}
private String LabelForBound(string boundType) //<todo.eoin Replace this with enums
private string LabelForBound(string boundType) //<todo.eoin Replace this with enums
{
return Loc.GetString($"air-alarm-ui-thresholds-{boundType}");
}
public void UpdateThresholdData(AtmosAlarmThreshold threshold, float currentAmount)
{
threshold.CheckThreshold(currentAmount, out AtmosAlarmType alarm, out AtmosMonitorThresholdBound which);
threshold.CheckThreshold(currentAmount, out var alarm, out var bound);
var upperDangerState = AtmosAlarmType.Normal;
var lowerDangerState = AtmosAlarmType.Normal;
var upperWarningState = AtmosAlarmType.Normal;
var lowerWarningState = AtmosAlarmType.Normal;
if(alarm == AtmosAlarmType.Danger)
switch (alarm)
{
if(which == AtmosMonitorThresholdBound.Upper) upperDangerState = alarm;
else lowerDangerState = alarm;
}
else if(alarm == AtmosAlarmType.Warning)
{
if(which == AtmosMonitorThresholdBound.Upper) upperWarningState = alarm;
else lowerWarningState = alarm;
case AtmosAlarmType.Danger:
{
if (bound == AtmosMonitorThresholdBound.Upper)
upperDangerState = alarm;
else
lowerDangerState = alarm;
break;
}
case AtmosAlarmType.Warning:
{
if (bound == AtmosMonitorThresholdBound.Upper)
upperWarningState = alarm;
else
lowerWarningState = alarm;
break;
}
}
_upperBoundControl.SetValue(threshold.UpperBound.Value);

View File

@@ -1,3 +1,4 @@
using System.Globalization;
using System.Linq;
using System.Numerics;
using Content.Client.Atmos.EntitySystems;
@@ -101,14 +102,9 @@ public sealed class AtmosDebugOverlay : Overlay
else
{
// Red-Green-Blue interpolation
if (interp < 0.5f)
{
res = Color.InterpolateBetween(Color.Red, Color.LimeGreen, interp * 2);
}
else
{
res = Color.InterpolateBetween(Color.LimeGreen, Color.Blue, (interp - 0.5f) * 2);
}
res = interp < 0.5f
? Color.InterpolateBetween(Color.Red, Color.LimeGreen, interp * 2)
: Color.InterpolateBetween(Color.LimeGreen, Color.Blue, (interp - 0.5f) * 2);
}
res = res.WithAlpha(0.75f);
@@ -181,7 +177,10 @@ public sealed class AtmosDebugOverlay : Overlay
handle.DrawCircle(tileCentre, 0.05f, Color.Black);
}
private void CheckAndShowBlockDir(AtmosDebugOverlayData data, DrawingHandleWorld handle, AtmosDirection dir,
private void CheckAndShowBlockDir(
AtmosDebugOverlayData data,
DrawingHandleWorld handle,
AtmosDirection dir,
Vector2 tileCentre)
{
if (!data.BlockDirection.HasFlag(dir))
@@ -243,7 +242,7 @@ public sealed class AtmosDebugOverlay : Overlay
var moles = data.Moles == null
? "No Air"
: data.Moles.Sum().ToString();
: data.Moles.Sum().ToString(CultureInfo.InvariantCulture);
handle.DrawString(_font, pos, $"Moles: {moles}");
pos += offset;
@@ -263,7 +262,12 @@ public sealed class AtmosDebugOverlay : Overlay
private void GetGrids(MapId mapId, Box2Rotated box)
{
_grids.Clear();
_mapManager.FindGridsIntersecting(mapId, box, ref _grids, (EntityUid uid, MapGridComponent grid,
_mapManager.FindGridsIntersecting(
mapId,
box,
ref _grids,
(EntityUid uid,
MapGridComponent grid,
ref List<(Entity<MapGridComponent>, DebugMessage)> state) =>
{
if (_system.TileData.TryGetValue(uid, out var data))

View File

@@ -30,7 +30,7 @@ public sealed class ClientClothingSystem : ClothingSystem
/// For some context, im currently refactoring inventory. Part of that is slots not being indexed by a massive enum anymore, but by strings.
/// Problem here: Every rsi-state is using the old enum-names in their state. I already used the new inventoryslots ALOT. tldr: its this or another week of renaming files.
/// </summary>
private static readonly Dictionary<string, string> TemporarySlotMap = new()
public static readonly Dictionary<string, string> TemporarySlotMap = new() //CP14 Public
{
{"head", "HELMET"},
{"eyes", "EYES"},

View File

@@ -7,7 +7,7 @@ using Robust.Client.GameObjects;
namespace Content.Client.Clothing;
public sealed class FlippableClothingVisualizerSystem : VisualizerSystem<FlippableClothingVisualsComponent>
public sealed class FlippableClothingVisualizerSystem : VisualizerSystem<FlippableClothingVisualsComponent>
{
[Dependency] private readonly SharedItemSystem _itemSys = default!;

View File

@@ -0,0 +1,95 @@
using Content.Shared.Electrocution;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Player;
namespace Content.Client.Electrocution;
/// <summary>
/// Shows the Electrocution HUD to entities with the ShowElectrocutionHUDComponent.
/// </summary>
public sealed class ElectrocutionHUDVisualizerSystem : VisualizerSystem<ElectrocutionHUDVisualsComponent>
{
[Dependency] private readonly IPlayerManager _playerMan = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ShowElectrocutionHUDComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<ShowElectrocutionHUDComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<ShowElectrocutionHUDComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<ShowElectrocutionHUDComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
}
private void OnPlayerAttached(Entity<ShowElectrocutionHUDComponent> ent, ref LocalPlayerAttachedEvent args)
{
ShowHUD();
}
private void OnPlayerDetached(Entity<ShowElectrocutionHUDComponent> ent, ref LocalPlayerDetachedEvent args)
{
RemoveHUD();
}
private void OnInit(Entity<ShowElectrocutionHUDComponent> ent, ref ComponentInit args)
{
if (_playerMan.LocalEntity == ent)
{
ShowHUD();
}
}
private void OnShutdown(Entity<ShowElectrocutionHUDComponent> ent, ref ComponentShutdown args)
{
if (_playerMan.LocalEntity == ent)
{
RemoveHUD();
}
}
// Show the HUD to the client.
// We have to look for all current entities that can be electrified and toggle the HUD layer on if they are.
private void ShowHUD()
{
var electrifiedQuery = AllEntityQuery<ElectrocutionHUDVisualsComponent, AppearanceComponent, SpriteComponent>();
while (electrifiedQuery.MoveNext(out var uid, out var _, out var appearanceComp, out var spriteComp))
{
if (!AppearanceSystem.TryGetData<bool>(uid, ElectrifiedVisuals.IsElectrified, out var electrified, appearanceComp))
continue;
if (electrified)
spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, true);
else
spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, false);
}
}
// Remove the HUD from the client.
// Find all current entities that can be electrified and hide the HUD layer.
private void RemoveHUD()
{
var electrifiedQuery = AllEntityQuery<ElectrocutionHUDVisualsComponent, AppearanceComponent, SpriteComponent>();
while (electrifiedQuery.MoveNext(out var uid, out var _, out var appearanceComp, out var spriteComp))
{
spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, false);
}
}
// Toggle the HUD layer if an entity becomes (de-)electrified
protected override void OnAppearanceChange(EntityUid uid, ElectrocutionHUDVisualsComponent comp, ref AppearanceChangeEvent args)
{
if (args.Sprite == null)
return;
if (!AppearanceSystem.TryGetData<bool>(uid, ElectrifiedVisuals.IsElectrified, out var electrified, args.Component))
return;
var player = _playerMan.LocalEntity;
if (electrified && HasComp<ShowElectrocutionHUDComponent>(player))
args.Sprite.LayerSetVisible(ElectrifiedLayers.HUD, true);
else
args.Sprite.LayerSetVisible(ElectrifiedLayers.HUD, false);
}
}

View File

@@ -55,7 +55,7 @@ namespace Content.Client.Eui
/// </summary>
protected void SendMessage(EuiMessageBase msg)
{
var netMsg = _netManager.CreateNetMessage<MsgEuiMessage>();
var netMsg = new MsgEuiMessage();
netMsg.Id = Id;
netMsg.Message = msg;

View File

@@ -112,7 +112,12 @@ namespace Content.Client.Ghost
_actions.RemoveAction(uid, component.ToggleLightingActionEntity);
_actions.RemoveAction(uid, component.ToggleFoVActionEntity);
_actions.RemoveAction(uid, component.ToggleGhostsActionEntity);
_actions.RemoveAction(uid, component.ToggleGhostHearingActionEntity);
//_actions.RemoveAction(uid, component.ToggleGhostHearingActionEntity); //Dont need in CP14
//CP14
_actions.RemoveAction(uid, component.CP14ZLevelUpActionEntity);
_actions.RemoveAction(uid, component.CP14ZLevelDownActionEntity);
_actions.RemoveAction(uid, component.CP14ToggleRoofActionEntity);
//CP14 end
if (uid != _playerManager.LocalEntity)
return;

View File

@@ -191,9 +191,15 @@ namespace Content.Client.Inventory
return;
if (ev.Function == ContentKeyFunctions.ExamineEntity)
{
_examine.DoExamine(slot.Entity.Value);
ev.Handle();
}
else if (ev.Function == EngineKeyFunctions.UseSecondary)
{
_ui.GetUIController<VerbMenuUIController>().OpenVerbMenu(slot.Entity.Value);
ev.Handle();
}
}
private void AddInventoryButton(EntityUid invUid, string slotId, InventoryComponent inv)

View File

@@ -21,6 +21,22 @@ public sealed class HandheldLightSystem : SharedHandheldLightSystem
SubscribeLocalEvent<HandheldLightComponent, AppearanceChangeEvent>(OnAppearanceChange);
}
/// <remarks>
/// TODO: Not properly predicted yet. Don't call this function if you want a the actual return value!
/// </remarks>
public override bool TurnOff(Entity<HandheldLightComponent> ent, bool makeNoise = true)
{
return true;
}
/// <remarks>
/// TODO: Not properly predicted yet. Don't call this function if you want a the actual return value!
/// </remarks>
public override bool TurnOn(EntityUid user, Entity<HandheldLightComponent> uid)
{
return true;
}
private void OnAppearanceChange(EntityUid uid, HandheldLightComponent? component, ref AppearanceChangeEvent args)
{
if (!Resolve(uid, ref component))

View File

@@ -116,7 +116,7 @@ namespace Content.Client.Lobby
return;
}
Lobby!.StationTime.Text = Loc.GetString("lobby-state-player-status-round-not-started");
Lobby!.StationTime.Text = Loc.GetString("lobby-state-player-status-round-not-started");
string text;
if (_gameTicker.Paused)
@@ -136,6 +136,10 @@ namespace Content.Client.Lobby
{
text = Loc.GetString(seconds < -5 ? "lobby-state-right-now-question" : "lobby-state-right-now-confirmation");
}
else if (difference.TotalHours >= 1)
{
text = $"{Math.Floor(difference.TotalHours)}:{difference.Minutes:D2}:{difference.Seconds:D2}";
}
else
{
text = $"{difference.Minutes}:{difference.Seconds:D2}";

View File

@@ -35,7 +35,7 @@ public sealed partial class StencilOverlay
var matty = Matrix3x2.Multiply(matrix, invMatrix);
worldHandle.SetTransform(matty);
foreach (var tile in grid.Comp.GetTilesIntersecting(worldAABB))
foreach (var tile in _map.GetTilesIntersecting(grid.Owner, grid, worldAABB))
{
// Ignored tiles for stencil
if (_weather.CanWeatherAffect(grid.Owner, grid, tile))

View File

@@ -26,6 +26,7 @@ public sealed partial class StencilOverlay : Overlay
[Dependency] private readonly IPrototypeManager _protoManager = default!;
private readonly ParallaxSystem _parallax;
private readonly SharedTransformSystem _transform;
private readonly SharedMapSystem _map;
private readonly SpriteSystem _sprite;
private readonly WeatherSystem _weather;
@@ -35,11 +36,12 @@ public sealed partial class StencilOverlay : Overlay
private readonly ShaderInstance _shader;
public StencilOverlay(ParallaxSystem parallax, SharedTransformSystem transform, SpriteSystem sprite, WeatherSystem weather)
public StencilOverlay(ParallaxSystem parallax, SharedTransformSystem transform, SharedMapSystem map, SpriteSystem sprite, WeatherSystem weather)
{
ZIndex = ParallaxSystem.ParallaxZIndex + 1;
_parallax = parallax;
_transform = transform;
_map = map;
_sprite = sprite;
_weather = weather;
IoCManager.InjectDependencies(this);

View File

@@ -10,13 +10,14 @@ public sealed class StencilOverlaySystem : EntitySystem
[Dependency] private readonly IOverlayManager _overlay = default!;
[Dependency] private readonly ParallaxSystem _parallax = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly WeatherSystem _weather = default!;
public override void Initialize()
{
base.Initialize();
_overlay.AddOverlay(new StencilOverlay(_parallax, _transform, _sprite, _weather));
_overlay.AddOverlay(new StencilOverlay(_parallax, _transform, _map, _sprite, _weather));
}
public override void Shutdown()

View File

@@ -116,7 +116,7 @@ public partial class BaseShuttleControl : MapGridControl
}
}
protected void DrawGrid(DrawingHandleScreen handle, Matrix3x2 matrix, Entity<MapGridComponent> grid, Color color, float alpha = 0.01f)
protected void DrawGrid(DrawingHandleScreen handle, Matrix3x2 gridToView, Entity<MapGridComponent> grid, Color color, float alpha = 0.01f)
{
var rator = Maps.GetAllTilesEnumerator(grid.Owner, grid.Comp);
var minimapScale = MinimapScale;
@@ -264,7 +264,7 @@ public partial class BaseShuttleControl : MapGridControl
Extensions.EnsureLength(ref _allVertices, totalData);
_drawJob.MidPoint = midpoint;
_drawJob.Matrix = matrix;
_drawJob.Matrix = gridToView;
_drawJob.MinimapScale = minimapScale;
_drawJob.Vertices = gridData.Vertices;
_drawJob.ScaledVertices = _allVertices;
@@ -286,7 +286,7 @@ public partial class BaseShuttleControl : MapGridControl
private record struct GridDrawJob : IParallelRobustJob
{
public int BatchSize => 16;
public int BatchSize => 64;
public float MinimapScale;
public Vector2 MidPoint;
@@ -297,12 +297,7 @@ public partial class BaseShuttleControl : MapGridControl
public void Execute(int index)
{
var vert = Vertices[index];
var adjustedVert = Vector2.Transform(vert, Matrix);
adjustedVert = adjustedVert with { Y = -adjustedVert.Y };
var scaledVert = ScalePosition(adjustedVert, MinimapScale, MidPoint);
ScaledVertices[index] = scaledVert;
ScaledVertices[index] = Vector2.Transform(Vertices[index], Matrix);
}
}
}

View File

@@ -15,6 +15,7 @@ public sealed partial class NavScreen : BoxContainer
[Dependency] private readonly IEntityManager _entManager = default!;
private SharedTransformSystem _xformSystem;
private EntityUid? _consoleEntity; // Entity of controlling console
private EntityUid? _shuttleEntity;
public NavScreen()
@@ -35,6 +36,12 @@ public sealed partial class NavScreen : BoxContainer
_shuttleEntity = shuttle;
}
public void SetConsole(EntityUid? console)
{
_consoleEntity = console;
NavRadar.SetConsole(console);
}
private void OnIFFTogglePressed(BaseButton.ButtonEventArgs args)
{
NavRadar.ShowIFF ^= true;

View File

@@ -138,6 +138,7 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
{
var coordinates = _entManager.GetCoordinates(cState.NavState.Coordinates);
NavContainer.SetShuttle(coordinates?.EntityId);
NavContainer.SetConsole(owner);
MapContainer.SetShuttle(coordinates?.EntityId);
MapContainer.SetConsole(owner);

View File

@@ -107,16 +107,19 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
DrawCircles(handle);
var gridNent = EntManager.GetNetEntity(GridEntity);
var mapPos = _xformSystem.ToMapCoordinates(_coordinates.Value);
var ourGridMatrix = _xformSystem.GetWorldMatrix(GridEntity.Value);
var dockMatrix = Matrix3Helpers.CreateTransform(_coordinates.Value.Position, Angle.Zero);
var worldFromDock = Matrix3x2.Multiply(dockMatrix, ourGridMatrix);
var ourGridToWorld = _xformSystem.GetWorldMatrix(GridEntity.Value);
var selectedDockToOurGrid = Matrix3Helpers.CreateTransform(_coordinates.Value.Position, Angle.Zero);
var selectedDockToWorld = Matrix3x2.Multiply(selectedDockToOurGrid, ourGridToWorld);
Matrix3x2.Invert(worldFromDock, out var offsetMatrix);
Box2 viewBoundsWorld = Matrix3Helpers.TransformBox(selectedDockToWorld, new Box2(-WorldRangeVector, WorldRangeVector));
Matrix3x2.Invert(selectedDockToWorld, out var worldToSelectedDock);
var selectedDockToView = Matrix3x2.CreateScale(new Vector2(MinimapScale, -MinimapScale)) * Matrix3x2.CreateTranslation(MidPointVector);
// Draw nearby grids
var controlBounds = PixelSizeBox;
_grids.Clear();
_mapManager.FindGridsIntersecting(gridXform.MapID, new Box2(mapPos.Position - WorldRangeVector, mapPos.Position + WorldRangeVector), ref _grids);
_mapManager.FindGridsIntersecting(gridXform.MapID, viewBoundsWorld, ref _grids);
// offset the dotted-line position to the bounds.
Vector2? viewedDockPos = _viewedState != null ? MidPointVector : null;
@@ -136,11 +139,11 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
if (grid.Owner != GridEntity && !_shuttles.CanDraw(grid.Owner, iffComp: iffComp))
continue;
var gridMatrix = _xformSystem.GetWorldMatrix(grid.Owner);
var matty = Matrix3x2.Multiply(gridMatrix, offsetMatrix);
var curGridToWorld = _xformSystem.GetWorldMatrix(grid.Owner);
var curGridToView = curGridToWorld * worldToSelectedDock * selectedDockToView;
var color = _shuttles.GetIFFColor(grid.Owner, grid.Owner == GridEntity, component: iffComp);
DrawGrid(handle, matty, grid, color);
DrawGrid(handle, curGridToView, grid, color);
// Draw any docks on that grid
if (!DockState.Docks.TryGetValue(EntManager.GetNetEntity(grid), out var gridDocks))
@@ -151,23 +154,24 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
if (ViewedDock == dock.Entity)
continue;
var position = Vector2.Transform(dock.Coordinates.Position, matty);
var otherDockRotation = Matrix3Helpers.CreateRotation(dock.Angle);
var scaledPos = ScalePosition(position with {Y = -position.Y});
if (!controlBounds.Contains(scaledPos.Floored()))
// This box is the AABB of all the vertices we draw below.
var dockRenderBoundsLocal = new Box2(-0.5f, -0.7f, 0.5f, 0.5f);
var currentDockToCurGrid = Matrix3Helpers.CreateTransform(dock.Coordinates.Position, dock.Angle);
var currentDockToWorld = Matrix3x2.Multiply(currentDockToCurGrid, curGridToWorld);
var dockRenderBoundsWorld = Matrix3Helpers.TransformBox(currentDockToWorld, dockRenderBoundsLocal);
if (!viewBoundsWorld.Intersects(dockRenderBoundsWorld))
continue;
// Draw the dock's collision
var collisionBL = Vector2.Transform(dock.Coordinates.Position +
Vector2.Transform(new Vector2(-0.2f, -0.7f), otherDockRotation), matty);
Vector2.Transform(new Vector2(-0.2f, -0.7f), otherDockRotation), curGridToView);
var collisionBR = Vector2.Transform(dock.Coordinates.Position +
Vector2.Transform(new Vector2(0.2f, -0.7f), otherDockRotation), matty);
Vector2.Transform(new Vector2(0.2f, -0.7f), otherDockRotation), curGridToView);
var collisionTR = Vector2.Transform(dock.Coordinates.Position +
Vector2.Transform(new Vector2(0.2f, -0.5f), otherDockRotation), matty);
Vector2.Transform(new Vector2(0.2f, -0.5f), otherDockRotation), curGridToView);
var collisionTL = Vector2.Transform(dock.Coordinates.Position +
Vector2.Transform(new Vector2(-0.2f, -0.5f), otherDockRotation), matty);
Vector2.Transform(new Vector2(-0.2f, -0.5f), otherDockRotation), curGridToView);
var verts = new[]
{
@@ -181,13 +185,6 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
collisionBL,
};
for (var i = 0; i < verts.Length; i++)
{
var vert = verts[i];
vert.Y = -vert.Y;
verts[i] = ScalePosition(vert);
}
var collisionCenter = verts[0] + verts[1] + verts[3] + verts[5];
var otherDockConnection = Color.ToSrgb(Color.Pink);
@@ -195,10 +192,10 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
handle.DrawPrimitives(DrawPrimitiveTopology.LineList, verts, otherDockConnection);
// Draw the dock itself
var dockBL = Vector2.Transform(dock.Coordinates.Position + new Vector2(-0.5f, -0.5f), matty);
var dockBR = Vector2.Transform(dock.Coordinates.Position + new Vector2(0.5f, -0.5f), matty);
var dockTR = Vector2.Transform(dock.Coordinates.Position + new Vector2(0.5f, 0.5f), matty);
var dockTL = Vector2.Transform(dock.Coordinates.Position + new Vector2(-0.5f, 0.5f), matty);
var dockBL = Vector2.Transform(dock.Coordinates.Position + new Vector2(-0.5f, -0.5f), curGridToView);
var dockBR = Vector2.Transform(dock.Coordinates.Position + new Vector2(0.5f, -0.5f), curGridToView);
var dockTR = Vector2.Transform(dock.Coordinates.Position + new Vector2(0.5f, 0.5f), curGridToView);
var dockTL = Vector2.Transform(dock.Coordinates.Position + new Vector2(-0.5f, 0.5f), curGridToView);
verts = new[]
{
@@ -212,13 +209,6 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
dockBL
};
for (var i = 0; i < verts.Length; i++)
{
var vert = verts[i];
vert.Y = -vert.Y;
verts[i] = ScalePosition(vert);
}
Color otherDockColor;
if (HighlightedDock == dock.Entity)
@@ -253,9 +243,11 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
collisionCenter /= 4;
var range = viewedDockPos.Value - collisionCenter;
if (range.Length() < SharedDockingSystem.DockingHiglightRange * MinimapScale)
var maxRange = SharedDockingSystem.DockingHiglightRange * MinimapScale;
var maxRangeSq = maxRange * maxRange;
if (range.LengthSquared() < maxRangeSq)
{
if (_viewedState?.GridDockedWith == null)
if (dock.GridDockedWith == null)
{
var coordsOne = EntManager.GetCoordinates(_viewedState!.Coordinates);
var coordsTwo = EntManager.GetCoordinates(dock.Coordinates);
@@ -265,10 +257,11 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
var rotA = _xformSystem.GetWorldRotation(coordsOne.EntityId) + _viewedState!.Angle;
var rotB = _xformSystem.GetWorldRotation(coordsTwo.EntityId) + dock.Angle;
var distance = (mapOne.Position - mapTwo.Position).Length();
var distanceSq = (mapOne.Position - mapTwo.Position).LengthSquared();
var inAlignment = _dockSystem.InAlignment(mapOne, rotA, mapTwo, rotB);
var canDock = distance < SharedDockingSystem.DockRange && inAlignment;
var maxDockDistSq = SharedDockingSystem.DockRange * SharedDockingSystem.DockRange;
var canDock = distanceSq < maxDockDistSq && inAlignment;
if (dockButton != null)
dockButton.Disabled = !canDock || !canDockChange;
@@ -297,7 +290,8 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
{
// Because it's being layed out top-down we have to arrange for first frame.
container.Arrange(PixelRect);
var containerPos = scaledPos / UIScale - container.DesiredSize / 2 - new Vector2(0f, 0.75f) * MinimapScale;
var dockPositionInView = Vector2.Transform(dock.Coordinates.Position, curGridToView);
var containerPos = dockPositionInView / UIScale - container.DesiredSize / 2 - new Vector2(0f, 0.75f) * MinimapScale;
SetPosition(container, containerPos);
}

View File

@@ -29,6 +29,11 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
/// </summary>
private EntityCoordinates? _coordinates;
/// <summary>
/// Entity of controlling console
/// </summary>
private EntityUid? _consoleEntity;
private Angle? _rotation;
private Dictionary<NetEntity, List<DockingPortState>> _docks = new();
@@ -57,6 +62,11 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
_rotation = angle;
}
public void SetConsole(EntityUid? consoleEntity)
{
_consoleEntity = consoleEntity;
}
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
{
base.KeyBindUp(args);
@@ -139,40 +149,35 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
}
var mapPos = _transform.ToMapCoordinates(_coordinates.Value);
var offset = _coordinates.Value.Position;
var posMatrix = Matrix3Helpers.CreateTransform(offset, _rotation.Value);
var posMatrix = Matrix3Helpers.CreateTransform(_coordinates.Value.Position, _rotation.Value);
var ourEntRot = RotateWithEntity ? _transform.GetWorldRotation(xform) : _rotation.Value;
var ourEntMatrix = Matrix3Helpers.CreateTransform(_transform.GetWorldPosition(xform), ourEntRot);
var ourWorldMatrix = Matrix3x2.Multiply(posMatrix, ourEntMatrix);
Matrix3x2.Invert(ourWorldMatrix, out var ourWorldMatrixInvert);
var shuttleToWorld = Matrix3x2.Multiply(posMatrix, ourEntMatrix);
Matrix3x2.Invert(shuttleToWorld, out var worldToShuttle);
var shuttleToView = Matrix3x2.CreateScale(new Vector2(MinimapScale, -MinimapScale)) * Matrix3x2.CreateTranslation(MidPointVector);
// Draw our grid in detail
var ourGridId = xform.GridUid;
if (EntManager.TryGetComponent<MapGridComponent>(ourGridId, out var ourGrid) &&
fixturesQuery.HasComponent(ourGridId.Value))
{
var ourGridMatrix = _transform.GetWorldMatrix(ourGridId.Value);
var matrix = Matrix3x2.Multiply(ourGridMatrix, ourWorldMatrixInvert);
var ourGridToWorld = _transform.GetWorldMatrix(ourGridId.Value);
var ourGridToShuttle = Matrix3x2.Multiply(ourGridToWorld, worldToShuttle);
var ourGridToView = ourGridToShuttle * shuttleToView;
var color = _shuttles.GetIFFColor(ourGridId.Value, self: true);
DrawGrid(handle, matrix, (ourGridId.Value, ourGrid), color);
DrawDocks(handle, ourGridId.Value, matrix);
DrawGrid(handle, ourGridToView, (ourGridId.Value, ourGrid), color);
DrawDocks(handle, ourGridId.Value, ourGridToView);
}
var invertedPosition = _coordinates.Value.Position - offset;
invertedPosition.Y = -invertedPosition.Y;
// Don't need to transform the InvWorldMatrix again as it's already offset to its position.
// Draw radar position on the station
var radarPos = invertedPosition;
const float radarVertRadius = 2f;
var radarPosVerts = new Vector2[]
{
ScalePosition(radarPos + new Vector2(0f, -radarVertRadius)),
ScalePosition(radarPos + new Vector2(radarVertRadius / 2f, 0f)),
ScalePosition(radarPos + new Vector2(0f, radarVertRadius)),
ScalePosition(radarPos + new Vector2(radarVertRadius / -2f, 0f)),
ScalePosition(new Vector2(0f, -radarVertRadius)),
ScalePosition(new Vector2(radarVertRadius / 2f, 0f)),
ScalePosition(new Vector2(0f, radarVertRadius)),
ScalePosition(new Vector2(radarVertRadius / -2f, 0f)),
};
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, radarPosVerts, Color.Lime);
@@ -197,8 +202,8 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
if (!_shuttles.CanDraw(gUid, gridBody, iff))
continue;
var gridMatrix = _transform.GetWorldMatrix(gUid);
var matty = Matrix3x2.Multiply(gridMatrix, ourWorldMatrixInvert);
var curGridToWorld = _transform.GetWorldMatrix(gUid);
var curGridToView = curGridToWorld * worldToShuttle * shuttleToView;
var labelColor = _shuttles.GetIFFColor(grid, self: false, iff);
var coordColor = new Color(labelColor.R * 0.8f, labelColor.G * 0.8f, labelColor.B * 0.8f, 0.5f);
@@ -213,8 +218,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
{
var gridBounds = grid.Comp.LocalAABB;
var gridCentre = Vector2.Transform(gridBody.LocalCenter, matty);
gridCentre.Y = -gridCentre.Y;
var gridCentre = Vector2.Transform(gridBody.LocalCenter, curGridToView);
var distance = gridCentre.Length();
var labelText = Loc.GetString("shuttle-console-iff-label", ("name", labelName),
@@ -230,9 +234,8 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
// y-offset the control to always render below the grid (vertically)
var yOffset = Math.Max(gridBounds.Height, gridBounds.Width) * MinimapScale / 1.8f;
// The actual position in the UI. We centre the label by offsetting the matrix position
// by half the label's width, plus the y-offset
var gridScaledPosition = ScalePosition(gridCentre) - new Vector2(0, -yOffset);
// The actual position in the UI.
var gridScaledPosition = gridCentre - new Vector2(0, -yOffset);
// Normalize the grid position if it exceeds the viewport bounds
// normalizing it instead of clamping it preserves the direction of the vector and prevents corner-hugging
@@ -264,18 +267,32 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
}
// Detailed view
var gridAABB = gridMatrix.TransformBox(grid.Comp.LocalAABB);
var gridAABB = curGridToWorld.TransformBox(grid.Comp.LocalAABB);
// Skip drawing if it's out of range.
if (!gridAABB.Intersects(viewAABB))
continue;
DrawGrid(handle, matty, grid, labelColor);
DrawDocks(handle, gUid, matty);
DrawGrid(handle, curGridToView, grid, labelColor);
DrawDocks(handle, gUid, curGridToView);
}
// If we've set the controlling console, and it's on a different grid
// to the shuttle itself, then draw an additional marker to help the
// player determine where they are relative to the shuttle.
if (_consoleEntity != null && xformQuery.TryGetComponent(_consoleEntity, out var consoleXform))
{
if (consoleXform.ParentUid != _coordinates.Value.EntityId)
{
var consolePositionWorld = _transform.GetWorldPosition((EntityUid)_consoleEntity);
var p = Vector2.Transform(consolePositionWorld, worldToShuttle * shuttleToView);
handle.DrawCircle(p, 5, Color.ToSrgb(Color.Cyan), true);
}
}
}
private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3x2 matrix)
private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3x2 gridToView)
{
if (!ShowDocks)
return;
@@ -283,33 +300,32 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
const float DockScale = 0.6f;
var nent = EntManager.GetNetEntity(uid);
const float sqrt2 = 1.41421356f;
const float dockRadius = DockScale * sqrt2;
// Worst-case bounds used to cull a dock:
Box2 viewBounds = new Box2(-dockRadius, -dockRadius, Size.X + dockRadius, Size.Y + dockRadius);
if (_docks.TryGetValue(nent, out var docks))
{
foreach (var state in docks)
{
var position = state.Coordinates.Position;
var uiPosition = Vector2.Transform(position, matrix);
if (uiPosition.Length() > (WorldRange * 2f) - DockScale)
var positionInView = Vector2.Transform(position, gridToView);
if (!viewBounds.Contains(positionInView))
{
continue;
}
var color = Color.ToSrgb(Color.Magenta);
var verts = new[]
{
Vector2.Transform(position + new Vector2(-DockScale, -DockScale), matrix),
Vector2.Transform(position + new Vector2(DockScale, -DockScale), matrix),
Vector2.Transform(position + new Vector2(DockScale, DockScale), matrix),
Vector2.Transform(position + new Vector2(-DockScale, DockScale), matrix),
Vector2.Transform(position + new Vector2(-DockScale, -DockScale), gridToView),
Vector2.Transform(position + new Vector2(DockScale, -DockScale), gridToView),
Vector2.Transform(position + new Vector2(DockScale, DockScale), gridToView),
Vector2.Transform(position + new Vector2(-DockScale, DockScale), gridToView),
};
for (var i = 0; i < verts.Length; i++)
{
var vert = verts[i];
vert.Y = -vert.Y;
verts[i] = ScalePosition(vert);
}
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, verts, color.WithAlpha(0.8f));
handle.DrawPrimitives(DrawPrimitiveTopology.LineStrip, verts, color);
}

View File

@@ -9,6 +9,7 @@ using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Content.Client.Silicons.Laws.Ui;
@@ -18,8 +19,13 @@ public sealed partial class LawDisplay : Control
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly EntityManager _entityManager = default!;
private static readonly TimeSpan PressCooldown = TimeSpan.FromSeconds(3);
private readonly Dictionary<Button, TimeSpan> _nextAllowedPress = new();
public LawDisplay(EntityUid uid, SiliconLaw law, HashSet<string>? radioChannels)
{
RobustXamlLoader.Load(this);
@@ -47,9 +53,12 @@ public sealed partial class LawDisplay : Control
MinWidth = 75,
};
_nextAllowedPress[localButton] = TimeSpan.Zero;
localButton.OnPressed += _ =>
{
_chatManager.SendMessage($"{lawIdentifierPlaintext}: {lawDescriptionPlaintext}", ChatSelectChannel.Local);
_nextAllowedPress[localButton] = _timing.CurTime + PressCooldown;
};
LawAnnouncementButtons.AddChild(localButton);
@@ -71,6 +80,8 @@ public sealed partial class LawDisplay : Control
MinWidth = 75,
};
_nextAllowedPress[radioChannelButton] = TimeSpan.Zero;
radioChannelButton.OnPressed += _ =>
{
switch (radioChannel)
@@ -80,9 +91,21 @@ public sealed partial class LawDisplay : Control
default:
_chatManager.SendMessage($"{SharedChatSystem.RadioChannelPrefix}{radioChannelProto.KeyCode} {lawIdentifierPlaintext}: {lawDescriptionPlaintext}", ChatSelectChannel.Radio); break;
}
_nextAllowedPress[radioChannelButton] = _timing.CurTime + PressCooldown;
};
LawAnnouncementButtons.AddChild(radioChannelButton);
}
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
var curTime = _timing.CurTime;
foreach (var (button, nextPress) in _nextAllowedPress)
{
button.Disabled = curTime < nextPress;
}
}
}

View File

@@ -1,6 +1,6 @@
<widgets:AlertsUI xmlns="https://spacestation14.io"
xmlns:widgets="clr-namespace:Content.Client.UserInterface.Systems.Alerts.Widgets"
MinSize="64 64">
MinSize="96 96">
<PanelContainer HorizontalAlignment="Right" VerticalAlignment="Top">
<BoxContainer Name="AlertContainer" Access="Public" Orientation="Vertical" />
</PanelContainer>

View File

@@ -16,9 +16,8 @@ using static Robust.Client.UserInterface.Controls.LineEdit;
namespace Content.Client.UserInterface.Systems.Chat.Widgets;
[GenerateTypedNameReferences]
#pragma warning disable RA0003
[Virtual]
public partial class ChatBox : UIWidget
#pragma warning restore RA0003
{
private readonly ChatUIController _controller;
private readonly IEntityManager _entManager;

View File

@@ -71,6 +71,7 @@ namespace Content.Client.UserInterface.Systems.Ghost.Controls.Roles
buttonHeading.AddStyleClass(ContainerButton.StyleClassButton);
buttonHeading.Label.HorizontalAlignment = HAlignment.Center;
buttonHeading.Label.HorizontalExpand = true;
buttonHeading.Margin = new Thickness(8, 0, 8, 2);
var body = new CollapsibleBody
{

View File

@@ -83,22 +83,27 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
if (args.Function == EngineKeyFunctions.UIClick)
{
_handsSystem.UIHandClick(_playerHandsComponent, hand.SlotName);
args.Handle();
}
else if (args.Function == EngineKeyFunctions.UseSecondary)
{
_handsSystem.UIHandOpenContextMenu(hand.SlotName);
args.Handle();
}
else if (args.Function == ContentKeyFunctions.ActivateItemInWorld)
{
_handsSystem.UIHandActivate(hand.SlotName);
args.Handle();
}
else if (args.Function == ContentKeyFunctions.AltActivateItemInWorld)
{
_handsSystem.UIHandAltActivateItem(hand.SlotName);
args.Handle();
}
else if (args.Function == ContentKeyFunctions.ExamineEntity)
{
_handsSystem.UIInventoryExamine(hand.SlotName);
args.Handle();
}
}

View File

@@ -160,8 +160,9 @@ public sealed class ItemGridPiece : Control, IEntityControl
}
// typically you'd divide by two, but since the textures are half a tile, this is done implicitly
var iconPosition = new Vector2((boundingGrid.Width + 1) * size.X + itemComponent.StoredOffset.X * 2,
(boundingGrid.Height + 1) * size.Y + itemComponent.StoredOffset.Y * 2);
var iconPosition = new Vector2(
(boundingGrid.Width + 1) * size.X + Location.Rotation.RotateVec(itemComponent.StoredOffset).X * 2,
(boundingGrid.Height + 1) * size.Y + Location.Rotation.RotateVec(itemComponent.StoredOffset).Y * 2);
var iconRotation = Location.Rotation + Angle.FromDegrees(itemComponent.StoredRotation);
if (itemComponent.StoredSprite is { } storageSprite)

View File

@@ -206,8 +206,7 @@ namespace Content.Client.Wires.UI
(_statusContainer = new GridContainer
{
Margin = new Thickness(8, 4),
// TODO: automatically change columns count.
Columns = 3
Rows = 2
})
}
}
@@ -227,7 +226,8 @@ namespace Content.Client.Wires.UI
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.FromHex("#525252ff")}
});
CloseButton.OnPressed += _ => Close();
SetSize = new Vector2(320, 200);
SetHeight = 200;
MinWidth = 320;
}
@@ -503,6 +503,8 @@ namespace Content.Client.Wires.UI
public StatusLight(StatusLightData data, IResourceCache resourceCache)
{
HorizontalAlignment = HAlignment.Right;
var hsv = Color.ToHsv(data.Color);
hsv.Z /= 2;
var dimColor = Color.FromHsv(hsv);

View File

@@ -0,0 +1,213 @@
using Content.Client.Clothing;
using Content.Shared._CP14.ModularCraft;
using Content.Shared._CP14.ModularCraft.Components;
using Content.Shared.Clothing;
using Content.Shared.Hands;
using Content.Shared.Inventory;
using Content.Shared.Item;
using Content.Shared.Wieldable.Components;
using Robust.Client.GameObjects;
using Robust.Client.ResourceManagement;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations;
namespace Content.Client._CP14.ModularCraft;
public sealed class CP14ClientModularCraftSystem : CP14SharedModularCraftSystem
{
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IResourceCache _resCache = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14ModularCraftStartPointComponent, AfterAutoHandleStateEvent>(OnAfterHandleState);
SubscribeLocalEvent<CP14ModularCraftStartPointComponent, GetInhandVisualsEvent>(OnGetInhandVisuals);
SubscribeLocalEvent<CP14ModularCraftStartPointComponent, GetEquipmentVisualsEvent>(OnGetEquipmentVisuals);
}
private void OnAfterHandleState(Entity<CP14ModularCraftStartPointComponent> start,
ref AfterAutoHandleStateEvent args)
{
if (!TryComp<SpriteComponent>(start, out var sprite))
return;
UpdateIcon(start, sprite);
}
private void UpdateIcon(Entity<CP14ModularCraftStartPointComponent> start, SpriteComponent? sprite = null)
{
if (!Resolve(start, ref sprite, false))
return;
//Remove old layers
foreach (var key in start.Comp.RevealedLayers)
{
sprite.RemoveLayer(key);
}
start.Comp.RevealedLayers.Clear();
//Add new layers
var counterPart = 0;
foreach (var part in start.Comp.InstalledParts)
{
var indexedPart = _proto.Index(part);
if (indexedPart.IconSprite is null)
{
//Try get default sprite
if (indexedPart.RsiPath is null)
continue;
var state = $"icon";
var rsi = _resCache
.GetResource<RSIResource>(SpriteSpecifierSerializer.TextureRoot / indexedPart.RsiPath)
.RSI;
if (!rsi.TryGetState(state, out _))
continue;
var defaultLayer = new PrototypeLayerData
{
RsiPath = indexedPart.RsiPath,
State = state,
};
var keyCode = $"cp14-modular-icon-layer-{counterPart}-default";
start.Comp.RevealedLayers.Add(keyCode);
var index = sprite.AddLayer(defaultLayer);
sprite.LayerMapSet(keyCode, index);
}
else
{
var counter = 0;
foreach (var layer in indexedPart.IconSprite)
{
var keyCode = $"cp14-modular-icon-layer-{counterPart}-{counter}";
start.Comp.RevealedLayers.Add(keyCode);
var index = sprite.AddLayer(layer);
sprite.LayerMapSet(keyCode, index);
counter++;
}
}
counterPart++;
}
}
private void OnGetInhandVisuals(Entity<CP14ModularCraftStartPointComponent> start, ref GetInhandVisualsEvent args)
{
var defaultKey = $"cp14-modular-inhand-layer-{args.Location.ToString().ToLowerInvariant()}";
if (!TryComp<ItemComponent>(start, out var item))
return;
var wielded = item.HeldPrefix == "wielded"; //SHITCOOOOOOODE
var counterPart = 0;
foreach (var part in start.Comp.InstalledParts)
{
var indexedPart = _proto.Index(part);
var targetLayers =
wielded ? indexedPart.WieldedInhandVisuals : indexedPart.InhandVisuals;
if (targetLayers is not null && targetLayers.TryGetValue(args.Location, out var layers))
{
var i = 0;
foreach (var layer in layers)
{
var key = $"{defaultKey}-{counterPart}-{i}";
args.Layers.Add((key, layer));
i++;
}
}
else
{
//Try get default visuals
if (indexedPart.RsiPath is null)
continue;
var rsi = _resCache
.GetResource<RSIResource>(SpriteSpecifierSerializer.TextureRoot / indexedPart.RsiPath)
.RSI;
var state = $"inhand-{args.Location.ToString().ToLowerInvariant()}";
if (wielded)
state = $"wielded-{state}";
if (!rsi.TryGetState(state, out _))
continue;
var defaultLayer = new PrototypeLayerData
{
RsiPath = indexedPart.RsiPath,
State = state,
};
var key = $"{defaultKey}-{counterPart}-default";
args.Layers.Add((key, defaultLayer));
}
counterPart++;
}
}
private void OnGetEquipmentVisuals(Entity<CP14ModularCraftStartPointComponent> start,
ref GetEquipmentVisualsEvent args)
{
if (!TryComp(args.Equipee, out InventoryComponent? inventory))
return;
var defaultKey = $"cp14-modular-clothing-layer-{args.Slot}";
var counterPart = 0;
foreach (var part in start.Comp.InstalledParts)
{
var indexedPart = _proto.Index(part);
if (indexedPart.ClothingVisuals is not null && indexedPart.ClothingVisuals.TryGetValue(args.Slot, out var layers))
{
var i = 0;
foreach (var layer in layers)
{
var key = $"{defaultKey}-{counterPart}-{i}";
args.Layers.Add((key, layer));
i++;
}
}
else
{
//Try get default sprites
if (indexedPart.RsiPath is null)
continue;
var rsi = _resCache
.GetResource<RSIResource>(SpriteSpecifierSerializer.TextureRoot / indexedPart.RsiPath)
.RSI;
if (!ClientClothingSystem.TemporarySlotMap.TryGetValue(args.Slot, out var correctedSlot))
continue;
var state = $"equipped-{correctedSlot}";
if (!rsi.TryGetState(state, out _))
continue;
var defaultLayer = new PrototypeLayerData
{
RsiPath = indexedPart.RsiPath,
State = state,
};
var key = $"{defaultKey}-{counterPart}-default";
args.Layers.Add((key, defaultLayer));
}
}
}
}

View File

@@ -0,0 +1,127 @@
using Content.Shared._CP14.Roof;
using Content.Shared.Ghost;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Console;
using Robust.Shared.Map.Components;
namespace Content.Client._CP14.Roof;
public sealed class CP14RoofSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
private bool _roofVisible = true;
public bool DisabledByCommand = false;
private EntityQuery<GhostComponent> _ghostQuery;
private EntityQuery<TransformComponent> _xformQuery;
public bool RoofVisibility
{
get => _roofVisible && !DisabledByCommand;
set
{
_roofVisible = value;
UpdateRoofVisibilityAll();
}
}
public override void Initialize()
{
base.Initialize();
_ghostQuery = GetEntityQuery<GhostComponent>();
_xformQuery = GetEntityQuery<TransformComponent>();
SubscribeLocalEvent<CP14RoofComponent, ComponentStartup>(RoofStartup);
SubscribeLocalEvent<GhostComponent, CP14ToggleRoofVisibilityAction>(OnToggleRoof);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var player = _playerManager.LocalEntity;
if (_ghostQuery.HasComp(player))
return;
if (_xformQuery.TryComp(player, out var playerXform))
{
var grid = playerXform.GridUid;
if (grid == null || !TryComp<MapGridComponent>(grid, out var gridComp))
return;
var roofQuery = GetEntityQuery<CP14RoofComponent>();
var anchored = _map.GetAnchoredEntities(grid.Value, gridComp, playerXform.Coordinates);
var underRoof = false;
foreach (var ent in anchored)
{
if (!roofQuery.HasComp(ent))
continue;
underRoof = true;
}
if (underRoof && _roofVisible)
{
RoofVisibility = false;
}
if (!underRoof && !_roofVisible)
{
RoofVisibility = true;
}
}
}
private void OnToggleRoof(Entity<GhostComponent> ent, ref CP14ToggleRoofVisibilityAction args)
{
if (args.Handled)
return;
DisabledByCommand = !DisabledByCommand;
UpdateRoofVisibilityAll();
args.Handled = true;
}
private void RoofStartup(Entity<CP14RoofComponent> ent, ref ComponentStartup args)
{
if (!TryComp<SpriteComponent>(ent, out var sprite))
return;
UpdateVisibility(ent, sprite);
}
private void UpdateVisibility(Entity<CP14RoofComponent> ent, SpriteComponent sprite)
{
sprite.Visible = RoofVisibility;
}
public void UpdateRoofVisibilityAll()
{
var query = EntityQueryEnumerator<CP14RoofComponent, SpriteComponent>();
while (query.MoveNext(out var uid, out var marker, out var sprite))
{
UpdateVisibility((uid, marker), sprite);
}
}
}
internal sealed class ShowRoof : LocalizedCommands
{
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
public override string Command => "cp14_toggleroof";
public override string Help => "Toggle roof visibility";
public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
var roofSystem = _entitySystemManager.GetEntitySystem<CP14RoofSystem>();
roofSystem.DisabledByCommand = !roofSystem.DisabledByCommand;
roofSystem.UpdateRoofVisibilityAll();
}
}

View File

@@ -51,7 +51,7 @@ namespace Content.IntegrationTests.Tests
//CrystallEdge maps
"Village",
"Island",
"Comoss",
//CrystallEdge Map replacement end
};
@@ -197,6 +197,7 @@ namespace Content.IntegrationTests.Tests
targetGrid = gridEnt;
}
}
// Test shuttle can dock.
// This is done inside gamemap test because loading the map takes ages and we already have it.
var station = entManager.GetComponent<StationMemberComponent>(targetGrid!.Value).Station;

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>

View File

@@ -16,6 +16,7 @@ public sealed class GasProducerAnomalySystem : EntitySystem
{
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
public override void Initialize()
{
@@ -56,8 +57,11 @@ public sealed class GasProducerAnomalySystem : EntitySystem
return;
var localpos = xform.Coordinates.Position;
var tilerefs = grid.GetLocalTilesIntersecting(
new Box2(localpos + new Vector2(-radius, -radius), localpos + new Vector2(radius, radius))).ToArray();
var tilerefs = _map.GetLocalTilesIntersecting(
xform.GridUid.Value,
grid,
new Box2(localpos + new Vector2(-radius, -radius), localpos + new Vector2(radius, radius)))
.ToArray();
if (tilerefs.Length == 0)
return;

View File

@@ -448,6 +448,7 @@ namespace Content.Server.Atmos.EntitySystems
if (flammable.FireStacks > 0)
{
/* CP14 Airtight walls should burn too!
var air = _atmosphereSystem.GetContainingMixture(uid);
// If we're in an oxygenless environment, put the fire out.
@@ -456,7 +457,7 @@ namespace Content.Server.Atmos.EntitySystems
Extinguish(uid, flammable);
continue;
}
*/
var source = EnsureComp<IgnitionSourceComponent>(uid);
_ignitionSourceSystem.SetIgnited((uid, source));

View File

@@ -102,10 +102,12 @@ public sealed class LogicGateSystem : EntitySystem
if (args.Port == comp.InputPortA)
{
comp.StateA = state;
_appearance.SetData(uid, LogicGateVisuals.InputA, state == SignalState.High); //If A == High => Sets input A sprite to True
}
else if (args.Port == comp.InputPortB)
{
comp.StateB = state;
_appearance.SetData(uid, LogicGateVisuals.InputB, state == SignalState.High); //If B == High => Sets input B sprite to True
}
UpdateOutput(uid, comp);
@@ -143,6 +145,8 @@ public sealed class LogicGateSystem : EntitySystem
break;
}
_appearance.SetData(uid, LogicGateVisuals.Output, output);
// only send a payload if it actually changed
if (output != comp.LastOutput)
{

View File

@@ -18,7 +18,7 @@ using JetBrains.Annotations;
using Robust.Server.Audio;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Player;
using Robust.Shared.Map.Events;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -66,6 +66,42 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
SubscribeLocalEvent<NetworkConfiguratorComponent, BoundUserInterfaceCheckRangeEvent>(OnUiRangeCheck);
SubscribeLocalEvent<DeviceListComponent, ComponentRemove>(OnComponentRemoved);
SubscribeLocalEvent<BeforeSaveEvent>(OnMapSave);
}
private void OnMapSave(BeforeSaveEvent ev)
{
var enumerator = AllEntityQuery<NetworkConfiguratorComponent>();
while (enumerator.MoveNext(out var uid, out var conf))
{
if (CompOrNull<TransformComponent>(conf.ActiveDeviceList)?.MapUid != ev.Map)
continue;
// The linked device list is (probably) being saved. Make sure that the configurator is also being saved
// (i.e., not in the hands of a mapper/ghost). In the future, map saving should raise a separate event
// containing a set of all entities that are about to be saved, which would make checking this much easier.
// This is a shitty bandaid, and will force close the UI during auto-saves.
// TODO Map serialization refactor
var xform = Transform(uid);
if (xform.MapUid == ev.Map && IsSaveable(uid))
continue;
_uiSystem.CloseUi(uid, NetworkConfiguratorUiKey.Configure);
DebugTools.AssertNull(conf.ActiveDeviceList);
}
bool IsSaveable(EntityUid uid)
{
while (uid.IsValid())
{
if (Prototype(uid)?.MapSavable == false)
return false;
uid = Transform(uid).ParentUid;
}
return true;
}
}
private void OnUiRangeCheck(Entity<NetworkConfiguratorComponent> ent, ref BoundUserInterfaceCheckRangeEvent args)
@@ -485,6 +521,9 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
if (!TryComp(targetUid, out DeviceListComponent? list))
return;
if (TryComp(configurator.ActiveDeviceList, out DeviceListComponent? oldList))
oldList.Configurators.Remove(configuratorUid);
list.Configurators.Add(configuratorUid);
configurator.ActiveDeviceList = targetUid;
Dirty(configuratorUid, configurator);
@@ -758,7 +797,7 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
{
if (query.TryGetComponent(device, out var comp))
{
component.Devices[addr] = device;
component.Devices.Add(addr, device);
comp.Configurators.Add(uid);
}
}

View File

@@ -28,6 +28,7 @@ public sealed partial class DragonSystem : EntitySystem
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
private EntityQuery<CarpRiftsConditionComponent> _objQuery;
@@ -156,7 +157,7 @@ public sealed partial class DragonSystem : EntitySystem
}
// cant put a rift on solars
foreach (var tile in grid.GetTilesIntersecting(new Circle(_transform.GetWorldPosition(xform), RiftTileRadius), false))
foreach (var tile in _map.GetTilesIntersecting(xform.GridUid.Value, grid, new Circle(_transform.GetWorldPosition(xform), RiftTileRadius), false))
{
if (!tile.IsSpace(_tileDef))
continue;

View File

@@ -121,7 +121,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
activated.TimeLeft -= frameTime;
if (activated.TimeLeft <= 0 || !IsPowered(uid, electrified, transform))
{
_appearance.SetData(uid, ElectrifiedVisuals.IsPowered, false);
_appearance.SetData(uid, ElectrifiedVisuals.ShowSparks, false);
RemComp<ActivatedElectrifiedComponent>(uid);
}
}
@@ -217,7 +217,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
return false;
EnsureComp<ActivatedElectrifiedComponent>(uid);
_appearance.SetData(uid, ElectrifiedVisuals.IsPowered, true);
_appearance.SetData(uid, ElectrifiedVisuals.ShowSparks, true);
siemens *= electrified.SiemensCoefficient;
if (!DoCommonElectrocutionAttempt(targetUid, uid, ref siemens) || siemens <= 0)
@@ -488,15 +488,4 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
}
_audio.PlayPvs(electrified.ShockNoises, targetUid, AudioParams.Default.WithVolume(electrified.ShockVolume));
}
public void SetElectrifiedWireCut(Entity<ElectrifiedComponent> ent, bool value)
{
if (ent.Comp.IsWireCut == value)
{
return;
}
ent.Comp.IsWireCut = value;
Dirty(ent);
}
}

View File

@@ -134,13 +134,6 @@ public sealed class DrainSystem : SharedDrainSystem
}
drain.Accumulator -= drain.DrainFrequency;
// Disable ambient sound from emptying manually
if (!drain.AutoDrain)
{
_ambientSoundSystem.SetAmbience(uid, false);
continue;
}
if (!managerQuery.TryGetComponent(uid, out var manager))
continue;
@@ -160,41 +153,44 @@ public sealed class DrainSystem : SharedDrainSystem
// This will ensure that UnitsPerSecond is per second...
var amount = drain.UnitsPerSecond * drain.DrainFrequency;
_puddles.Clear();
_lookup.GetEntitiesInRange(Transform(uid).Coordinates, drain.Range, _puddles);
if (_puddles.Count == 0)
if (drain.AutoDrain)
{
_ambientSoundSystem.SetAmbience(uid, false);
continue;
}
_puddles.Clear();
_lookup.GetEntitiesInRange(Transform(uid).Coordinates, drain.Range, _puddles);
_ambientSoundSystem.SetAmbience(uid, true);
amount /= _puddles.Count;
foreach (var puddle in _puddles)
{
// Queue the solution deletion if it's empty. EvaporationSystem might also do this
// but queuedelete should be pretty safe.
if (!_solutionContainerSystem.ResolveSolution(puddle.Owner, puddle.Comp.SolutionName, ref puddle.Comp.Solution, out var puddleSolution))
if (_puddles.Count == 0)
{
EntityManager.QueueDeleteEntity(puddle);
_ambientSoundSystem.SetAmbience(uid, false);
continue;
}
// Removes the lowest of:
// the drain component's units per second adjusted for # of puddles
// the puddle's remaining volume (making it cleanly zero)
// the drain's remaining volume in its buffer.
var transferSolution = _solutionContainerSystem.SplitSolution(puddle.Comp.Solution.Value,
FixedPoint2.Min(FixedPoint2.New(amount), puddleSolution.Volume, drainSolution.AvailableVolume));
_ambientSoundSystem.SetAmbience(uid, true);
drainSolution.AddSolution(transferSolution, _prototypeManager);
amount /= _puddles.Count;
if (puddleSolution.Volume <= 0)
foreach (var puddle in _puddles)
{
QueueDel(puddle);
// Queue the solution deletion if it's empty. EvaporationSystem might also do this
// but queuedelete should be pretty safe.
if (!_solutionContainerSystem.ResolveSolution(puddle.Owner, puddle.Comp.SolutionName, ref puddle.Comp.Solution, out var puddleSolution))
{
EntityManager.QueueDeleteEntity(puddle);
continue;
}
// Removes the lowest of:
// the drain component's units per second adjusted for # of puddles
// the puddle's remaining volume (making it cleanly zero)
// the drain's remaining volume in its buffer.
var transferSolution = _solutionContainerSystem.SplitSolution(puddle.Comp.Solution.Value,
FixedPoint2.Min(FixedPoint2.New(amount), puddleSolution.Volume, drainSolution.AvailableVolume));
drainSolution.AddSolution(transferSolution, _prototypeManager);
if (puddleSolution.Volume <= 0)
{
QueueDel(puddle);
}
}
}

View File

@@ -25,7 +25,7 @@ public sealed partial class PuddleSystem
var tileRef = _maps.GetTileRef(xform.GridUid.Value, mapGrid, xform.Coordinates);
var tileDef = (ContentTileDefinition) _tileDefManager[tileRef.Tile.TypeId];
entity.Comp.CP14ForceEvaporation = tileDef.Weather;
entity.Comp.CP14ForceEvaporation = tileDef.SuckReagents;
}
//CP14 End force evaporation under sky
}

View File

@@ -1,7 +1,9 @@
using Content.Server.Popups;
using Content.Shared.Administration;
using Content.Shared.GameTicking;
using Content.Shared.Mind;
using Robust.Shared.Console;
using Content.Server.GameTicking;
namespace Content.Server.Ghost
{
@@ -23,6 +25,14 @@ namespace Content.Server.Ghost
return;
}
var gameTicker = _entities.System<GameTicker>();
if (!gameTicker.PlayerGameStatuses.TryGetValue(player.UserId, out var playerStatus) ||
playerStatus is not PlayerGameStatus.JoinedGame)
{
shell.WriteLine("ghost-command-error-lobby");
return;
}
if (player.AttachedEntity is { Valid: true } frozen &&
_entities.HasComponent<AdminFrozenComponent>(frozen))
{

View File

@@ -1,3 +1,5 @@
using System.Linq;
using System.Numerics;
using Content.Server.Administration.Logs;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
@@ -32,14 +34,13 @@ using Robust.Shared.Physics.Systems;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using System.Linq;
using System.Numerics;
namespace Content.Server.Ghost
{
public sealed class GhostSystem : SharedGhostSystem
{
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly IAdminLogManager _adminLog = default!;
[Dependency] private readonly SharedEyeSystem _eye = default!;
[Dependency] private readonly FollowerSystem _followerSystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
@@ -221,10 +222,15 @@ namespace Content.Server.Ghost
_actions.SetCooldown(component.BooActionEntity.Value, start, end);
}
_actions.AddAction(uid, ref component.ToggleGhostHearingActionEntity, component.ToggleGhostHearingAction);
//_actions.AddAction(uid, ref component.ToggleGhostHearingActionEntity, component.ToggleGhostHearingAction); //Dont need in CP14
_actions.AddAction(uid, ref component.ToggleLightingActionEntity, component.ToggleLightingAction);
_actions.AddAction(uid, ref component.ToggleFoVActionEntity, component.ToggleFoVAction);
_actions.AddAction(uid, ref component.ToggleGhostsActionEntity, component.ToggleGhostsAction);
//CP14
_actions.AddAction(uid, ref component.CP14ZLevelUpActionEntity, component.CP14ZLevelUpAction);
_actions.AddAction(uid, ref component.CP14ZLevelDownActionEntity, component.CP14ZLevelDownAction);
_actions.AddAction(uid, ref component.CP14ToggleRoofActionEntity, component.CP14ToggleRoofAction);
//CP14 end
}
private void OnGhostExamine(EntityUid uid, GhostComponent component, ExaminedEvent args)
@@ -330,6 +336,8 @@ namespace Content.Server.Ghost
private void WarpTo(EntityUid uid, EntityUid target)
{
_adminLog.Add(LogType.GhostWarp, $"{ToPrettyString(uid)} ghost warped to {ToPrettyString(target)}");
if ((TryComp(target, out WarpPointComponent? warp) && warp.Follow) || HasComp<MobStateComponent>(target))
{
_followerSystem.StartFollowingEntity(uid, target);

View File

@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using Content.Server.Administration;
using Content.Server.Ghost.Roles.Components;
using Content.Server.Ghost.Roles.Raffles;
@@ -77,13 +77,13 @@ namespace Content.Server.Ghost.Roles
if (isProto)
{
if (!_protoManager.TryIndex<GhostRoleRaffleSettingsPrototype>(args[4], out var proto))
if (!_protoManager.TryIndex<GhostRoleRaffleSettingsPrototype>(args[3], out var proto))
{
var validProtos = string.Join(", ",
_protoManager.EnumeratePrototypes<GhostRoleRaffleSettingsPrototype>().Select(p => p.ID)
);
shell.WriteLine($"{args[4]} is not a valid raffle settings prototype. Valid options: {validProtos}");
shell.WriteLine($"{args[3]} is not a valid raffle settings prototype. Valid options: {validProtos}");
return;
}

View File

@@ -92,11 +92,19 @@ public sealed class RandomGiftSystem : EntitySystem
var mapGridCompName = _componentFactory.GetComponentName(typeof(MapGridComponent));
var physicsCompName = _componentFactory.GetComponentName(typeof(PhysicsComponent));
if (!_prototype.TryIndex<EntityCategoryPrototype>("ForkFiltered", out var indexedFilter))
return;
foreach (var proto in _prototype.EnumeratePrototypes<EntityPrototype>())
{
if (proto.Abstract || proto.HideSpawnMenu || proto.Components.ContainsKey(mapGridCompName) || !proto.Components.ContainsKey(physicsCompName))
continue;
//CP14 Only cp14 items
if (!proto.Categories.Contains(indexedFilter))
continue;
//CP14 end
_possibleGiftsUnsafe.Add(proto.ID);
if (!proto.Components.ContainsKey(itemCompName))

View File

@@ -9,7 +9,6 @@ using Content.Shared.Light;
using Content.Shared.Light.Components;
using Content.Shared.Rounding;
using Content.Shared.Toggleable;
using Content.Shared.Verbs;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
@@ -46,7 +45,6 @@ namespace Content.Server.Light.EntitySystems
SubscribeLocalEvent<HandheldLightComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<HandheldLightComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<HandheldLightComponent, GetVerbsEvent<ActivationVerb>>(AddToggleLightVerb);
SubscribeLocalEvent<HandheldLightComponent, ActivateInWorldEvent>(OnActivate);
@@ -179,25 +177,7 @@ namespace Content.Server.Light.EntitySystems
}
}
private void AddToggleLightVerb(Entity<HandheldLightComponent> ent, ref GetVerbsEvent<ActivationVerb> args)
{
if (!args.CanAccess || !args.CanInteract || !ent.Comp.ToggleOnInteract)
return;
var @event = args;
ActivationVerb verb = new()
{
Text = Loc.GetString("verb-common-toggle-light"),
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/light.svg.192dpi.png")),
Act = ent.Comp.Activated
? () => TurnOff(ent)
: () => TurnOn(@event.User, ent)
};
args.Verbs.Add(verb);
}
public bool TurnOff(Entity<HandheldLightComponent> ent, bool makeNoise = true)
public override bool TurnOff(Entity<HandheldLightComponent> ent, bool makeNoise = true)
{
if (!ent.Comp.Activated || !_lights.TryGetLight(ent, out var pointLightComponent))
{
@@ -211,7 +191,7 @@ namespace Content.Server.Light.EntitySystems
return true;
}
public bool TurnOn(EntityUid user, Entity<HandheldLightComponent> uid)
public override bool TurnOn(EntityUid user, Entity<HandheldLightComponent> uid)
{
var component = uid.Comp;
if (component.Activated || !_lights.TryGetLight(uid, out var pointLightComponent))

View File

@@ -40,6 +40,7 @@ public sealed class NukeSystem : EntitySystem
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;
@@ -190,7 +191,7 @@ public sealed class NukeSystem : EntitySystem
var worldPos = _transform.GetWorldPosition(xform);
foreach (var tile in grid.GetTilesIntersecting(new Circle(worldPos, component.RequiredFloorRadius), false))
foreach (var tile in _map.GetTilesIntersecting(xform.GridUid.Value, grid, new Circle(worldPos, component.RequiredFloorRadius), false))
{
if (!tile.IsSpace(_tileDefManager))
continue;

View File

@@ -18,8 +18,11 @@ public sealed partial class CableComponent : Component
[DataField]
public EntProtoId CableDroppedOnCutPrototype = "CableHVStack1";
/// <summary>
/// The tool quality needed to cut the cable. Setting to null prevents cutting.
/// </summary>
[DataField]
public ProtoId<ToolQualityPrototype> CuttingQuality = SharedToolSystem.CutQuality;
public ProtoId<ToolQualityPrototype>? CuttingQuality = SharedToolSystem.CutQuality;
/// <summary>
/// Checked by <see cref="CablePlacerComponent"/> to determine if there is

View File

@@ -35,7 +35,7 @@ public sealed partial class CableSystem
var snapPos = grid.TileIndicesFor(args.ClickLocation);
var tileDef = (ContentTileDefinition) _tileManager[_map.GetTileRef(gridUid, grid,snapPos).Tile.TypeId];
if ((!tileDef.IsSubFloor || !tileDef.Sturdy) && placer.Comp.CP14OnlySubfloor) //CP14 if only subfloor
if (!tileDef.IsSubFloor || !tileDef.Sturdy)
return;
foreach (var anchored in grid.GetAnchoredEntities(snapPos))

View File

@@ -35,7 +35,10 @@ public sealed partial class CableSystem : EntitySystem
if (args.Handled)
return;
args.Handled = _toolSystem.UseTool(args.Used, args.User, uid, cable.CuttingDelay, cable.CuttingQuality, new CableCuttingFinishedEvent());
if (cable.CuttingQuality != null)
{
args.Handled = _toolSystem.UseTool(args.Used, args.User, uid, cable.CuttingDelay, cable.CuttingQuality, new CableCuttingFinishedEvent());
}
}
private void OnCableCut(EntityUid uid, CableComponent cable, DoAfterEvent args)

View File

@@ -17,7 +17,7 @@ public sealed partial class PowerWireAction : BaseWireAction
[DataField("pulseTimeout")]
private int _pulseTimeout = 30;
private ElectrocutionSystem _electrocutionSystem = default!;
private ElectrocutionSystem _electrocution = default!;
public override object StatusKey { get; } = PowerWireActionKey.Status;
@@ -105,8 +105,8 @@ public sealed partial class PowerWireAction : BaseWireAction
&& !EntityManager.TryGetComponent(used, out electrified))
return;
_electrocutionSystem.SetElectrifiedWireCut((used, electrified), setting);
electrified.Enabled = setting;
_electrocution.SetElectrifiedWireCut((used, electrified), setting);
_electrocution.SetElectrified((used, electrified), setting);
}
/// <returns>false if failed, true otherwise, or if the entity cannot be electrified</returns>
@@ -120,7 +120,7 @@ public sealed partial class PowerWireAction : BaseWireAction
// always set this to true
SetElectrified(wire.Owner, true, electrified);
var electrifiedAttempt = _electrocutionSystem.TryDoElectrifiedAct(wire.Owner, user);
var electrifiedAttempt = _electrocution.TryDoElectrifiedAct(wire.Owner, user);
// if we were electrified, then return false
return !electrifiedAttempt;
@@ -161,7 +161,7 @@ public sealed partial class PowerWireAction : BaseWireAction
{
base.Initialize();
_electrocutionSystem = EntityManager.System<ElectrocutionSystem>();
_electrocution = EntityManager.System<ElectrocutionSystem>();
}
// This should add a wire into the entity's state, whether it be

View File

@@ -58,7 +58,7 @@ public sealed partial class DungeonJob
}
}
if (tile is not null && biomeSystem.TryGetEntity(node, indexedBiome.Layers, tile.Value, seed, _grid, out var entityProto))
if (biomeSystem.TryGetEntity(node, indexedBiome.Layers, tile ?? tileRef.Value.Tile, seed, _grid, out var entityProto))
{
var ent = _entManager.SpawnEntity(entityProto, new EntityCoordinates(_gridUid, node + _grid.TileSizeHalfVector));
var xform = xformQuery.Get(ent);

View File

@@ -20,7 +20,11 @@ public sealed partial class DungeonJob
}
var tileDef = _prototype.Index(tileProto);
data.SpawnGroups.TryGetValue(DungeonDataKey.WallMounts, out var spawnProto);
if (!data.SpawnGroups.TryGetValue(DungeonDataKey.WallMounts, out var spawnProto))
{
// caves can have no walls
return;
}
var checkedTiles = new HashSet<Vector2i>();
var allExterior = new HashSet<Vector2i>(dungeon.CorridorExteriorTiles);

View File

@@ -45,7 +45,6 @@ public sealed class ProjectileSystem : SharedProjectileSystem
RaiseLocalEvent(uid, ref ev);
var otherName = ToPrettyString(target);
var direction = args.OurBody.LinearVelocity.Normalized();
var modifiedDamage = _damageableSystem.TryChangeDamage(target, ev.Damage, component.IgnoreResistances, origin: component.Shooter);
var deleted = Deleted(target);
@@ -64,7 +63,9 @@ public sealed class ProjectileSystem : SharedProjectileSystem
if (!deleted)
{
_guns.PlayImpactSound(target, modifiedDamage, component.SoundHit, component.ForceSound);
_sharedCameraRecoil.KickCamera(target, direction);
if (!args.OurBody.LinearVelocity.IsLengthZero())
_sharedCameraRecoil.KickCamera(target, args.OurBody.LinearVelocity.Normalized());
}
component.DamagedEntity = true;

View File

@@ -21,6 +21,7 @@ public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly TurfSystem _turf = default!;
[Dependency] private readonly IChatManager _chat = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
@@ -105,7 +106,7 @@ public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem
var found = false;
foreach (var tile in grid.GetTilesIntersecting(circle))
foreach (var tile in _map.GetTilesIntersecting(entityGridUid.Value, grid, circle))
{
if (tile.IsSpace(_tileDefinitionManager)
|| _turf.IsTileBlocked(tile, CollisionGroup.MobMask)
@@ -176,7 +177,7 @@ public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem
var mapTarget = grid.WorldToTile(mapPos);
var circle = new Circle(mapPos, 2);
foreach (var newTileRef in grid.GetTilesIntersecting(circle))
foreach (var newTileRef in _map.GetTilesIntersecting(targetGrid, grid, circle))
{
if (newTileRef.IsSpace(_tileDefinitionManager) || _turf.IsTileBlocked(newTileRef, CollisionGroup.MobMask) || !_atmosphere.IsTileMixtureProbablySafe(targetGrid, targetMap, mapTarget))
continue;

View File

@@ -43,6 +43,7 @@ public sealed partial class RevenantSystem
[Dependency] private readonly TileSystem _tile = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
private void InitializeAbilities()
{
@@ -228,8 +229,12 @@ public sealed partial class RevenantSystem
var xform = Transform(uid);
if (!TryComp<MapGridComponent>(xform.GridUid, out var map))
return;
var tiles = map.GetTilesIntersecting(Box2.CenteredAround(_transformSystem.GetWorldPosition(xform),
new Vector2(component.DefileRadius * 2, component.DefileRadius))).ToArray();
var tiles = _mapSystem.GetTilesIntersecting(
xform.GridUid.Value,
map,
Box2.CenteredAround(_transformSystem.GetWorldPosition(xform),
new Vector2(component.DefileRadius * 2, component.DefileRadius)))
.ToArray();
_random.Shuffle(tiles);

View File

@@ -193,7 +193,7 @@ public sealed class SpawnSalvageMissionJob : Job<bool>
List<Vector2i> reservedTiles = new();
foreach (var tile in grid.GetTilesIntersecting(new Circle(Vector2.Zero, landingPadRadius), false))
foreach (var tile in _map.GetTilesIntersecting(mapUid, grid, new Circle(Vector2.Zero, landingPadRadius), false))
{
if (!_biome.TryGetBiomeTile(mapUid, grid, tile.GridIndices, out _))
continue;

View File

@@ -253,12 +253,6 @@ public sealed partial class ShuttleSystem
if (TryComp<PhysicsComponent>(shuttleUid, out var shuttlePhysics))
{
// Static physics type is set when station anchor is enabled
if (shuttlePhysics.BodyType == BodyType.Static)
{
reason = Loc.GetString("shuttle-console-static");
return false;
}
// Too large to FTL
if (FTLMassLimit > 0 && shuttlePhysics.Mass > FTLMassLimit)
@@ -1027,6 +1021,7 @@ public sealed partial class ShuttleSystem
continue;
}
// If it has the FTLSmashImmuneComponent ignore it.
if (_immuneQuery.HasComponent(ent))
{
continue;

View File

@@ -0,0 +1,37 @@
using Content.Shared.Silicons.Laws.Components;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
namespace Content.Server.Silicons.Laws;
/// <summary>
/// This handles running the ion storm event a on specific entity when that entity is spawned in.
/// </summary>
public sealed class StartIonStormedSystem : EntitySystem
{
[Dependency] private readonly IonStormSystem _ionStorm = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly SiliconLawSystem _siliconLaw = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StartIonStormedComponent, MapInitEvent>(OnMapInit);
}
private void OnMapInit(Entity<StartIonStormedComponent> ent, ref MapInitEvent args)
{
if (!TryComp<SiliconLawBoundComponent>(ent.Owner, out var lawBound))
return;
if (!TryComp<IonStormTargetComponent>(ent.Owner, out var target))
return;
for (int currentIonStorm = 0; currentIonStorm < ent.Comp.IonStormAmount; currentIonStorm++)
{
_ionStorm.IonStormTarget((ent.Owner, lawBound, target), false);
}
var laws = _siliconLaw.GetLaws(ent.Owner, lawBound);
_adminLogger.Add(LogType.Mind, LogImpact.High, $"{ToPrettyString(ent.Owner):silicon} spawned with ion stormed laws: {laws.LoggingString()}");
}
}

View File

@@ -308,7 +308,7 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem
foreach (var grid in grids)
{
// TODO: Remover grid.Owner when this iterator returns entityuids as well.
AttemptConsumeTiles(uid, grid.Comp.GetTilesIntersecting(circle), grid, grid, eventHorizon);
AttemptConsumeTiles(uid, _mapSystem.GetTilesIntersecting(grid.Owner, grid.Comp, circle), grid, grid, eventHorizon);
}
}

View File

@@ -0,0 +1,38 @@
using Content.Server.StationEvents.Events;
using Content.Shared.Access;
using Content.Shared.Destructible.Thresholds;
using Robust.Shared.Prototypes;
namespace Content.Server.StationEvents.Components;
/// <summary>
/// Greytide Virus event specific configuration
/// </summary>
[RegisterComponent, Access(typeof(GreytideVirusRule))]
public sealed partial class GreytideVirusRuleComponent : Component
{
/// <summary>
/// Range from which the severity is randomly picked from.
/// </summary>
[DataField]
public MinMax SeverityRange = new(1, 3);
/// <summary>
/// Severity corresponding to the number of access groups affected.
/// Will pick randomly from the SeverityRange if not specified.
/// </summary>
[DataField]
public int? Severity;
/// <summary>
/// Access groups to pick from.
/// </summary>
[DataField]
public List<ProtoId<AccessGroupPrototype>> AccessGroups = new();
/// <summary>
/// Entities with this access level will be ignored.
/// </summary>
[DataField]
public List<ProtoId<AccessLevelPrototype>> Blacklist = new();
}

View File

@@ -148,20 +148,20 @@ public sealed class EventManagerSystem : EntitySystem
return null;
}
var sumOfWeights = 0;
var sumOfWeights = 0.0f;
foreach (var stationEvent in availableEvents.Values)
{
sumOfWeights += (int) stationEvent.Weight;
sumOfWeights += stationEvent.Weight;
}
sumOfWeights = _random.Next(sumOfWeights);
sumOfWeights = _random.NextFloat(sumOfWeights);
foreach (var (proto, stationEvent) in availableEvents)
{
sumOfWeights -= (int) stationEvent.Weight;
sumOfWeights -= stationEvent.Weight;
if (sumOfWeights <= 0)
if (sumOfWeights <= 0.0f)
{
return proto.ID;
}

View File

@@ -0,0 +1,96 @@
using Content.Server.StationEvents.Components;
using Content.Shared.Access;
using Content.Shared.Access.Systems;
using Content.Shared.Access.Components;
using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems;
using Content.Shared.Lock;
using Content.Shared.GameTicking.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.StationEvents.Events;
/// <summary>
/// Greytide Virus event
/// This will open and bolt airlocks and unlock lockers from randomly selected access groups.
/// </summary>
public sealed class GreytideVirusRule : StationEventSystem<GreytideVirusRuleComponent>
{
[Dependency] private readonly AccessReaderSystem _access = default!;
[Dependency] private readonly SharedDoorSystem _door = default!;
[Dependency] private readonly LockSystem _lock = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IRobustRandom _random = default!;
protected override void Added(EntityUid uid, GreytideVirusRuleComponent virusComp, GameRuleComponent gameRule, GameRuleAddedEvent args)
{
if (!TryComp<StationEventComponent>(uid, out var stationEvent))
return;
// pick severity randomly from range if not specified otherwise
virusComp.Severity ??= virusComp.SeverityRange.Next(_random);
virusComp.Severity = Math.Min(virusComp.Severity.Value, virusComp.AccessGroups.Count);
stationEvent.StartAnnouncement = Loc.GetString("station-event-greytide-virus-start-announcement", ("severity", virusComp.Severity.Value));
base.Added(uid, virusComp, gameRule, args);
}
protected override void Started(EntityUid uid, GreytideVirusRuleComponent virusComp, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
base.Started(uid, virusComp, gameRule, args);
if (virusComp.Severity == null)
return;
// pick random access groups
var chosen = _random.GetItems(virusComp.AccessGroups, virusComp.Severity.Value, allowDuplicates: false);
// combine all the selected access groups
var accessIds = new HashSet<ProtoId<AccessLevelPrototype>>();
foreach (var group in chosen)
{
if (_prototype.TryIndex(group, out var proto))
accessIds.UnionWith(proto.Tags);
}
var firelockQuery = GetEntityQuery<FirelockComponent>();
var accessQuery = GetEntityQuery<AccessReaderComponent>();
var lockQuery = AllEntityQuery<LockComponent>();
while (lockQuery.MoveNext(out var lockUid, out var lockComp))
{
if (!accessQuery.TryComp(lockUid, out var accessComp))
continue;
// check access
// the AreAccessTagsAllowed function is a little weird because it technically has support for certain tags to be locked out of opening something
// which might have unintened side effects (see the comments in the function itself)
// but no one uses that yet, so it is fine for now
if (!_access.AreAccessTagsAllowed(accessIds, accessComp) || _access.AreAccessTagsAllowed(virusComp.Blacklist, accessComp))
continue;
// open lockers
_lock.Unlock(lockUid, null, lockComp);
}
var airlockQuery = AllEntityQuery<AirlockComponent, DoorComponent>();
while (airlockQuery.MoveNext(out var airlockUid, out var airlockComp, out var doorComp))
{
// don't space everything
if (firelockQuery.HasComp(airlockUid))
continue;
// use the access reader from the door electronics if they exist
if (!_access.GetMainAccessReader(airlockUid, out var accessComp))
continue;
// check access
if (!_access.AreAccessTagsAllowed(accessIds, accessComp) || _access.AreAccessTagsAllowed(virusComp.Blacklist, accessComp))
continue;
// open and bolt airlocks
_door.TryOpenAndBolt(airlockUid, doorComp, airlockComp);
}
}
}

View File

@@ -38,6 +38,7 @@ namespace Content.Server.VendingMachines
[Dependency] private readonly ThrowingSystem _throwingSystem = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SpeakOnUIClosedSystem _speakOnUIClosed = default!;
[Dependency] private readonly SharedPointLightSystem _light = default!;
private const float WallVendEjectDistanceFromWall = 1f;
@@ -334,6 +335,12 @@ namespace Content.Server.VendingMachines
finalState = VendingMachineVisualState.Off;
}
if (_light.TryGetLight(uid, out var pointlight))
{
var lightState = finalState != VendingMachineVisualState.Broken && finalState != VendingMachineVisualState.Off;
_light.SetEnabled(uid, lightState, pointlight);
}
_appearanceSystem.SetData(uid, VendingMachineVisuals.VisualState, finalState);
}

View File

@@ -22,13 +22,14 @@ public abstract partial class ComponentWireAction<TComponent> : BaseWireAction w
public override bool Cut(EntityUid user, Wire wire)
{
base.Cut(user, wire);
return EntityManager.TryGetComponent(wire.Owner, out TComponent? component) && Cut(user, wire, component);
// if the entity doesn't exist, we need to return true otherwise the wire sprite is never updated
return EntityManager.TryGetComponent(wire.Owner, out TComponent? component) ? Cut(user, wire, component) : true;
}
public override bool Mend(EntityUid user, Wire wire)
{
base.Mend(user, wire);
return EntityManager.TryGetComponent(wire.Owner, out TComponent? component) && Mend(user, wire, component);
return EntityManager.TryGetComponent(wire.Owner, out TComponent? component) ? Mend(user, wire, component) : true;
}
public override void Pulse(EntityUid user, Wire wire)

View File

@@ -4,7 +4,6 @@ using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
using Content.Shared.Maps;
using Content.Shared.Physics;
using Content.Shared.Throwing;
using Robust.Server.GameObjects;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Components;
using Robust.Shared.Random;
@@ -17,7 +16,8 @@ public sealed class ThrowArtifactSystem : EntitySystem
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly ThrowingSystem _throwing = default!;
[Dependency] private readonly TileSystem _tile = default!;
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
/// <inheritdoc/>
public override void Initialize()
@@ -30,7 +30,9 @@ public sealed class ThrowArtifactSystem : EntitySystem
var xform = Transform(uid);
if (TryComp<MapGridComponent>(xform.GridUid, out var grid))
{
var tiles = grid.GetTilesIntersecting(
var tiles = _mapSystem.GetTilesIntersecting(
xform.GridUid.Value,
grid,
Box2.CenteredAround(_transform.GetWorldPosition(xform), new Vector2(component.Range * 2, component.Range)));
foreach (var tile in tiles)

View File

@@ -2,7 +2,6 @@ using System.Numerics;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events;
using Content.Shared._CP14.Cargo;
using Content.Shared._CP14.Cargo.Prototype;
using Robust.Shared.Map;
using Robust.Shared.Random;
@@ -10,10 +9,8 @@ namespace Content.Server._CP14.Cargo;
public sealed partial class CP14CargoSystem
{
private EntityQuery<ArrivalsBlacklistComponent> _blacklistQuery;
private void InitializeShuttle()
{
_blacklistQuery = GetEntityQuery<ArrivalsBlacklistComponent>();
SubscribeLocalEvent<CP14TravelingStoreShipComponent, FTLCompletedEvent>(OnFTLCompleted);
}
@@ -46,11 +43,14 @@ public sealed partial class CP14CargoSystem
private void SendShuttleToStation(EntityUid shuttle, float startupTime = 0f)
{
var targetPoints = new List<EntityUid>();
var targetEnumerator = EntityQueryEnumerator<CP14TravelingStoreShipFTLTargetComponent, TransformComponent>(); //TODO - different method position location
var targetEnumerator =
EntityQueryEnumerator<CP14TravelingStoreShipFTLTargetComponent,
TransformComponent>(); //TODO - different method position location
while (targetEnumerator.MoveNext(out var uid, out _, out _))
{
targetPoints.Add(uid);
}
if (targetPoints.Count == 0)
return;
@@ -59,14 +59,23 @@ public sealed partial class CP14CargoSystem
var shuttleComp = Comp<ShuttleComponent>(shuttle);
_shuttles.FTLToCoordinates(shuttle, shuttleComp, targetXform.Coordinates, targetXform.LocalRotation, hyperspaceTime: 5f, startupTime: startupTime);
_shuttles.FTLToCoordinates(shuttle,
shuttleComp,
targetXform.Coordinates,
targetXform.LocalRotation,
hyperspaceTime: 20f,
startupTime: startupTime);
}
private void SendShuttleToTradepost(EntityUid shuttle, EntityUid tradePostMap)
{
var shuttleComp = Comp<ShuttleComponent>(shuttle);
_shuttles.FTLToCoordinates(shuttle, shuttleComp, new EntityCoordinates(tradePostMap, Vector2.Zero), Angle.Zero, hyperspaceTime: 5f);
_shuttles.FTLToCoordinates(shuttle,
shuttleComp,
new EntityCoordinates(tradePostMap, Vector2.Zero),
Angle.Zero,
hyperspaceTime: 20f);
}
private void OnFTLCompleted(Entity<CP14TravelingStoreShipComponent> ent, ref FTLCompletedEvent args)
@@ -74,24 +83,24 @@ public sealed partial class CP14CargoSystem
if (!TryComp<CP14StationTravelingStoreShipTargetComponent>(ent.Comp.Station, out var station))
return;
if (station.TradePostMap is not null && Transform(ent).MapUid == Transform(station.TradePostMap.Value).MapUid) //Landed on tradepost
if (station.TradePostMap is not null &&
Transform(ent).MapUid == Transform(station.TradePostMap.Value).MapUid) //Landed on tradepost
{
station.OnStation = false;
var b = station.Balance;
SellingThings((ent.Comp.Station, station)); // +balance
TopUpBalance((ent.Comp.Station, station)); //+balance
BuyToQueue((ent.Comp.Station, station)); //-balance +buyQueue
TrySpawnBuyedThings((ent.Comp.Station, station));
UpdateStorePositions((ent.Comp.Station, station));
}
else //Landed on station
else //Landed on station
{
station.OnStation = true;
CashOut((ent.Comp.Station, station));
}
UpdateAllStores();
}
}

View File

@@ -1,4 +1,5 @@
using Content.Server._CP14.Currency;
using Content.Server._CP14.RoundRemoveShuttle;
using Content.Server.Shuttles.Systems;
using Content.Server.Station.Events;
using Content.Server.Station.Systems;
@@ -8,8 +9,10 @@ using Content.Shared._CP14.Cargo.Prototype;
using Content.Shared.Maps;
using Content.Shared.Paper;
using Content.Shared.Physics;
using Content.Shared.Station.Components;
using Content.Shared.Storage;
using Content.Shared.Storage.EntitySystems;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
@@ -69,6 +72,18 @@ public sealed partial class CP14CargoSystem : CP14SharedCargoSystem
UpdateShuttle();
}
/// <summary>
/// Allows other systems to additionally add items to the queue that are brought to the settlement on a merchant ship.
/// </summary>
[PublicAPI]
public void AddBuyQueue(Entity<CP14StationTravelingStoreShipTargetComponent> station, List<EntProtoId> products)
{
foreach (var product in products)
{
station.Comp.BuyedQueue.Enqueue(product);
}
}
private void OnPostInit(Entity<CP14StationTravelingStoreShipTargetComponent> station, ref StationPostInitEvent args)
{
if (!Deleted(station.Comp.Shuttle))
@@ -85,28 +100,51 @@ public sealed partial class CP14CargoSystem : CP14SharedCargoSystem
var travelingStoreShipComp = EnsureComp<CP14TravelingStoreShipComponent>(station.Comp.Shuttle.Value);
travelingStoreShipComp.Station = station;
var member = EnsureComp<StationMemberComponent>(shuttle);
member.Station = station;
var roundRemover = EnsureComp<CP14RoundRemoveShuttleComponent>(shuttle);
roundRemover.Station = station;
station.Comp.NextTravelTime = _timing.CurTime + TimeSpan.FromSeconds(10f);
AddRoundstartTradingPositions(station);
UpdateStorePositions(station);
}
private void AddRoundstartTradingPositions(Entity<CP14StationTravelingStoreShipTargetComponent> station)
{
if (_buyProto is not null)
{
foreach (var buy in _buyProto)
{
if (buy.RoundstartAvailable)
station.Comp.AvailableBuyPosition.Add(buy);
}
}
if (_sellProto is not null)
{
foreach (var sell in _sellProto)
{
if (sell.RoundstartAvailable)
station.Comp.AvailableSellPosition.Add(sell);
}
}
}
private void UpdateStorePositions(Entity<CP14StationTravelingStoreShipTargetComponent> station)
{
station.Comp.CurrentBuyPositions.Clear();
station.Comp.CurrentSellPositions.Clear();
if (_buyProto is not null)
foreach (var buyPos in station.Comp.AvailableBuyPosition)
{
foreach (var buyPos in _buyProto)
{
station.Comp.CurrentBuyPositions.Add(buyPos, buyPos.Price.Next(_random)/10*10);
}
station.Comp.CurrentBuyPositions.Add(buyPos, buyPos.Price.Next(_random)/10*10);
}
if (_sellProto is not null)
foreach (var sellPos in station.Comp.AvailableSellPosition)
{
foreach (var sellPos in _sellProto)
{
station.Comp.CurrentSellPositions.Add(sellPos, sellPos.Price.Next(_random)/10*10);
}
station.Comp.CurrentSellPositions.Add(sellPos, sellPos.Price.Next(_random)/10*10);
}
}
@@ -222,7 +260,7 @@ public sealed partial class CP14CargoSystem : CP14SharedCargoSystem
foreach (var service in indexedBuyed.Services)
{
service.Buy(EntityManager, station);
service.Buy(EntityManager, _proto, station);
}
}
}
@@ -263,44 +301,10 @@ public sealed partial class CP14CargoSystem : CP14SharedCargoSystem
{
var coord = Transform(moneyBox.Value).Coordinates;
if (station.Comp.Balance > 0)
var coins = _currency.GenerateMoney(station.Comp.Balance, coord);
foreach (var coin in coins)
{
var coins = _currency.GenerateMoney(CP14SharedCurrencySystem.PP.Key, station.Comp.Balance, coord, out var remainder);
station.Comp.Balance = remainder;
foreach (var coin in coins)
{
_storage.Insert(moneyBox.Value, coin, out _);
}
}
if (station.Comp.Balance > 0)
{
var coins = _currency.GenerateMoney(CP14SharedCurrencySystem.GP.Key, station.Comp.Balance, coord, out var remainder);
station.Comp.Balance = remainder;
foreach (var coin in coins)
{
_storage.Insert(moneyBox.Value, coin, out _);
}
}
if (station.Comp.Balance > 0)
{
var coins = _currency.GenerateMoney(CP14SharedCurrencySystem.SP.Key, station.Comp.Balance, coord, out var remainder);
station.Comp.Balance = remainder;
foreach (var coin in coins)
{
_storage.Insert(moneyBox.Value, coin, out _);
}
}
if (station.Comp.Balance > 0)
{
var coins = _currency.GenerateMoney(CP14SharedCurrencySystem.CP.Key, station.Comp.Balance, coord, out var remainder);
station.Comp.Balance = remainder;
foreach (var coin in coins)
{
_storage.Insert(moneyBox.Value, coin, out _);
}
_storage.Insert(moneyBox.Value, coin, out _);
}
}
}

View File

@@ -1,6 +1,6 @@
namespace Content.Server._CP14.Cargo;
[RegisterComponent, Access(typeof(CP14CargoSystem)), AutoGenerateComponentPause]
[RegisterComponent, Access(typeof(CP14CargoSystem))]
public sealed partial class CP14TravelingStoreShipComponent : Component
{
[DataField]

View File

@@ -154,6 +154,56 @@ public sealed partial class CP14CurrencySystem
return spawns;
}
public HashSet<EntityUid> GenerateMoney(
int target,
EntityCoordinates coordinates)
{
HashSet<EntityUid> coins = new();
var balance = target;
//PP
if (balance > 0)
{
var ppCoin = GenerateMoney(PP.Key, balance, coordinates, out var remainder);
balance = remainder;
foreach (var pp in ppCoin)
{
coins.Add(pp);
}
}
//GP
if (balance > 0)
{
var gpCoin = GenerateMoney(GP.Key, balance, coordinates, out var remainder);
balance = remainder;
foreach (var gp in gpCoin)
{
coins.Add(gp);
}
}
//SP
if (balance > 0)
{
var spCoin = GenerateMoney(SP.Key, balance, coordinates, out var remainder);
balance = remainder;
foreach (var sp in spCoin)
{
coins.Add(sp);
}
}
//CP
if (balance > 0)
{
var cpCoin = GenerateMoney(CP.Key, balance, coordinates, out var remainder);
balance = remainder;
foreach (var cp in cpCoin)
{
coins.Add(cp);
}
}
return coins;
}
private bool ProcessEntity(EntityUid ent, ref int remainder, HashSet<EntityUid> spawns)
{
var singleCurrency = GetTotalCurrency(ent);

View File

@@ -0,0 +1,22 @@
using Content.Shared.Damage;
namespace Content.Server._CP14.DPSMeter;
[RegisterComponent]
public sealed partial class CP14DPSMeterComponent : Component
{
[DataField]
public DamageSpecifier TotalDamage = new DamageSpecifier();
[DataField]
public TimeSpan LastHitTime = TimeSpan.Zero;
[DataField]
public TimeSpan StartTrackTime = TimeSpan.Zero;
[DataField]
public TimeSpan EndTrackTime = TimeSpan.Zero;
[DataField]
public TimeSpan TrackTimeAfterHit = TimeSpan.FromSeconds(5f);
}

View File

@@ -0,0 +1,62 @@
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared.Popups;
using Robust.Shared.Timing;
namespace Content.Server._CP14.DPSMeter;
public sealed class CP14DPSMeterSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14DPSMeterComponent, DamageChangedEvent>(OnDamageChanged);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<CP14DPSMeterComponent>();
while (query.MoveNext(out var uid, out var meter))
{
if (_timing.CurTime < meter.EndTrackTime || meter.EndTrackTime == TimeSpan.Zero)
continue;
//Clear tracking
_popup.PopupEntity($"TOTAL DPS: {GetDPS((uid, meter))}", uid, PopupType.Large);
meter.TotalDamage = new DamageSpecifier();
meter.EndTrackTime = TimeSpan.Zero;
meter.StartTrackTime = TimeSpan.Zero;
}
}
private void OnDamageChanged(Entity<CP14DPSMeterComponent> ent, ref DamageChangedEvent args)
{
if (args.DamageDelta is null)
return;
ent.Comp.TotalDamage += args.DamageDelta;
if (ent.Comp.StartTrackTime == TimeSpan.Zero)
ent.Comp.StartTrackTime = _timing.CurTime;
ent.Comp.LastHitTime = _timing.CurTime;
ent.Comp.EndTrackTime = _timing.CurTime + ent.Comp.TrackTimeAfterHit;
_popup.PopupEntity($"DPS: {GetDPS(ent)}", ent);
}
private FixedPoint2 GetDPS(Entity<CP14DPSMeterComponent> ent)
{
var totalDamage = ent.Comp.TotalDamage.GetTotal();
var totalSeconds = (ent.Comp.LastHitTime - ent.Comp.StartTrackTime).TotalSeconds;
var DPS = totalDamage / Math.Max(totalSeconds, 1f);
return DPS;
}
}

View File

@@ -1,5 +1,4 @@
using Content.Server.Administration;
using Content.Shared._CP14.DayCycle;
using Content.Shared.Administration;
using Robust.Shared.Console;
using CP14DayCycleComponent = Content.Shared._CP14.DayCycle.Components.CP14DayCycleComponent;

View File

@@ -26,6 +26,7 @@ public sealed partial class CP14DemiplaneSystem
private const double JobMaxTime = 0.002;
[Dependency] private readonly ExamineSystemShared _examine = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
private void InitGeneration()
{
@@ -62,7 +63,7 @@ public sealed partial class CP14DemiplaneSystem
: Loc.GetString("cp14-demiplane-examine-title-unknown"));
List<LocId> modifierNames = new();
foreach (var modifier in comp.Modifiers)
foreach (var modifier in comp.SelectedModifiers)
{
if (!_proto.TryIndex(modifier, out var indexedModifier))
continue;
@@ -141,6 +142,23 @@ public sealed partial class CP14DemiplaneSystem
if (generator.Comp.Location is null)
return;
var curTime = _timing.CurTime;
if (curTime < generator.Comp.LastUseTime + generator.Comp.UseDelay)
return;
generator.Comp.LastUseTime = curTime;
if (generator.Comp.NeedDemiplaneCrystal)
{
var demiplaneCrystals = _lookup.GetEntitiesInRange<CP14DemiplaneCrystalComponent>(Transform(generator).Coordinates, generator.Comp.DemiplaneCrystalRange);
if (demiplaneCrystals.Count == 0)
{
return;
}
}
//We cant open demiplan in another demiplan or if parent is not Map
if (HasComp<CP14DemiplaneComponent>(Transform(generator).MapUid) || !HasComp<MapGridComponent>(_transform.GetParentUid(args.User)))
{
@@ -148,7 +166,7 @@ public sealed partial class CP14DemiplaneSystem
return;
}
SpawnRandomDemiplane(generator.Comp.Location.Value, generator.Comp.Modifiers, out var demiplane, out var mapId);
SpawnRandomDemiplane(generator.Comp.Location.Value, generator.Comp.SelectedModifiers, out var demiplane, out var mapId);
//Admin log needed
//TEST
@@ -178,14 +196,36 @@ public sealed partial class CP14DemiplaneSystem
suitableConfigs.Add(locationConfig);
}
if (suitableConfigs.Count == 0)
CP14DemiplaneLocationPrototype? selectedConfig = null;
while (suitableConfigs.Count > 0)
{
Log.Error("Expedition mission generation failed: No suitable location configs.");
var randomConfig = _random.Pick(suitableConfigs);
if (!generator.Comp.TiersContent.ContainsKey(randomConfig.Tier))
{
suitableConfigs.Remove(randomConfig);
continue;
}
if (!_random.Prob(generator.Comp.TiersContent[randomConfig.Tier]))
{
suitableConfigs.Remove(randomConfig);
continue;
}
selectedConfig = randomConfig;
break;
}
if (selectedConfig is null)
{
// We dont should be here
Log.Warning("Expedition mission generation failed: No suitable location configs.");
QueueDel(generator);
return;
}
var selectedConfig = _random.Pick(suitableConfigs);
generator.Comp.Location = selectedConfig;
//Modifier generation
@@ -204,42 +244,100 @@ public sealed partial class CP14DemiplaneSystem
}
//Tag required filter
foreach (var reqTag in modifier.RequiredTags)
if (passed)
{
if (!selectedConfig.Tags.Contains(reqTag))
foreach (var reqTag in modifier.RequiredTags)
{
if (!selectedConfig.Tags.Contains(reqTag))
{
passed = false;
break;
}
}
}
//Tier filter
if (passed)
{
foreach (var tier in modifier.Tiers)
{
if (!generator.Comp.TiersContent.ContainsKey(tier))
{
passed = false;
break;
}
}
}
// Tier weight filter
if (passed)
{
var maxProb = 0f;
foreach (var tier in modifier.Tiers)
{
maxProb = Math.Max(maxProb, generator.Comp.TiersContent[tier]);
}
if (!_random.Prob(maxProb))
{
passed = false;
}
}
//Random prob filter
if (passed)
{
if (!_random.Prob(modifier.GenerationProb))
{
passed = false;
}
}
if (passed)
suitableModifiersWeights.Add(modifier, modifier.GenerationWeight);
}
//Limits calculation
Dictionary<ProtoId<CP14DemiplaneModifierCategoryPrototype>, float> limits = new();
foreach (var limit in generator.Comp.Limits)
{
limits.Add(limit.Key, limit.Value);
}
while (suitableModifiersWeights.Count > 0)
{
var selectedModifier = ModifierPick(suitableModifiersWeights, _random);
//Fill demiplane under limits
var passed = true;
foreach (var category in selectedModifier.Categories)
{
if (!limits.ContainsKey(category.Key))
{
suitableModifiersWeights.Remove(selectedModifier);
passed = false;
break;
}
if (limits[category.Key] - category.Value < 0)
{
suitableModifiersWeights.Remove(selectedModifier);
passed = false;
break;
}
}
if (passed)
{
suitableModifiersWeights.Add(modifier, modifier.GenerationWeight);
}
}
var difficulty = 0f;
var reward = 0f;
while (generator.Comp.Modifiers.Count < generator.Comp.MaxModifiers && suitableModifiersWeights.Count > 0)
{
var selectedModifier = ModifierPick(suitableModifiersWeights, _random);
if (difficulty + selectedModifier.Difficulty > generator.Comp.DifficultyLimit)
{
suitableModifiersWeights.Remove(selectedModifier);
if (!passed)
continue;
}
if (reward + selectedModifier.Reward > generator.Comp.RewardLimit)
generator.Comp.SelectedModifiers.Add(selectedModifier);
foreach (var category in selectedModifier.Categories)
{
suitableModifiersWeights.Remove(selectedModifier);
continue;
limits[category.Key] -= category.Value;
}
generator.Comp.Modifiers.Add(selectedModifier);
reward += selectedModifier.Reward;
difficulty += selectedModifier.Difficulty;
if (selectedModifier.Unique)
suitableModifiersWeights.Remove(selectedModifier);
}
@@ -274,5 +372,4 @@ public sealed partial class CP14DemiplaneSystem
// Shouldn't happen
throw new InvalidOperationException($"Invalid weighted pick in CP14DemiplanSystem.Generation!");
}
}

View File

@@ -1,3 +1,4 @@
using Content.Server.Body.Systems;
using Content.Shared._CP14.Demiplane.Components;
using Content.Shared.Mobs.Systems;
@@ -9,6 +10,7 @@ public sealed partial class CP14DemiplaneSystem
private TimeSpan _nextCheckTime = TimeSpan.Zero;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly BodySystem _body = default!;
private void InitStabilization()
{
@@ -49,13 +51,26 @@ public sealed partial class CP14DemiplaneSystem
}
var query2 = EntityQueryEnumerator<CP14DemiplaneComponent, CP14DemiplaneDestroyWithoutStabilizationComponent>();
while (query2.MoveNext(out var uid, out var demiplan, out var stabilization))
while (query2.MoveNext(out var uid, out var demiplane, out var stabilization))
{
if (_timing.CurTime < stabilization.EndProtectionTime)
continue;
if (!stabilizedMaps.Contains(uid))
QueueDel(uid);
DeleteDemiplane((uid, demiplane));
}
}
private void DeleteDemiplane(Entity<CP14DemiplaneComponent> demiplane)
{
var query = EntityQueryEnumerator<CP14DemiplaneStabilizerComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var stabilizer, out var xform))
{
if (TryTeleportOutDemiplane(demiplane, uid))
_body.GibBody(uid);
}
QueueDel(demiplane);
}
}

View File

@@ -44,6 +44,7 @@ public sealed partial class CP14DemiplaneSystem : CP14SharedDemiplaneSystem
UpdateGeneration(frameTime);
UpdateStabilization(frameTime);
}
/// <summary>
/// Teleports the entity inside the demiplane, to one of the random entry points.
/// </summary>

View File

@@ -0,0 +1,6 @@
namespace Content.Server._CP14.Demiplane.Components;
[RegisterComponent, Access(typeof(CP14DemiplaneSystem))]
public sealed partial class CP14DemiplaneCrystalComponent : Component
{
}

View File

@@ -1,4 +1,3 @@
using Content.Shared._CP14.Demiplane.Components;
using Content.Shared._CP14.Demiplane.Prototypes;
using Robust.Shared.Prototypes;
@@ -14,14 +13,26 @@ public sealed partial class CP14DemiplaneGeneratorDataComponent : Component
public ProtoId<CP14DemiplaneLocationPrototype>? Location;
[DataField]
public List<ProtoId<CP14DemiplaneModifierPrototype>> Modifiers = new();
public List<ProtoId<CP14DemiplaneModifierPrototype>> SelectedModifiers = new();
/// <summary>
/// Generator Tier. Determines which modifiers and locations will be selected for this demiplane
/// </summary>
[DataField(required: true)]
public Dictionary<int, float> TiersContent = new();
[DataField(required: true)]
public Dictionary<ProtoId<CP14DemiplaneModifierCategoryPrototype>, float> Limits;
[DataField]
public float DifficultyLimit = 1;
public bool NeedDemiplaneCrystal = true;
[DataField]
public float RewardLimit = 1;
public float DemiplaneCrystalRange = 15f;
[DataField]
public int MaxModifiers = 6;
public TimeSpan UseDelay = TimeSpan.FromSeconds(1.0);
[DataField]
public TimeSpan LastUseTime = TimeSpan.Zero;
}

View File

@@ -108,9 +108,9 @@ public sealed class CP14SpawnRandomDemiplaneJob : Job<bool>
}
//Setup gravity
var gravity = _entManager.EnsureComponent<GravityComponent>(DemiplaneMapUid);
var gravity = _entManager.EnsureComponent<GravityComponent>(grid);
gravity.Enabled = true;
_entManager.Dirty(DemiplaneMapUid, gravity, metadata);
_entManager.Dirty(grid, gravity, metadata);
// Setup default atmos
var moles = new float[Atmospherics.AdjustedNumberOfGases];

View File

@@ -1,4 +1,5 @@
using Content.Server._CP14.Demiplane;
using Content.Server.Interaction;
using Content.Server.Mind;
using Content.Server.Popups;
using Content.Shared._CP14.Demiplane;
@@ -19,8 +20,8 @@ public sealed partial class CP14DemiplaneTravelingSystem : EntitySystem
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly InteractionSystem _interaction = default!;
public override void Initialize()
{
@@ -43,6 +44,7 @@ public sealed partial class CP14DemiplaneTravelingSystem : EntitySystem
passWay.NextTimeTeleport = _timing.CurTime + passWay.Delay;
//Get all teleporting entities
HashSet<EntityUid> teleportedEnts = new();
var nearestEnts = _lookup.GetEntitiesInRange(uid, passWay.Radius);
foreach (var ent in nearestEnts)
@@ -53,6 +55,9 @@ public sealed partial class CP14DemiplaneTravelingSystem : EntitySystem
if (!_mind.TryGetMind(ent, out var mindId, out var mind))
continue;
if (!_interaction.InRangeUnobstructed(ent, uid))
continue;
teleportedEnts.Add(ent);
}
@@ -61,6 +66,7 @@ public sealed partial class CP14DemiplaneTravelingSystem : EntitySystem
teleportedEnts.Remove(_random.Pick(teleportedEnts));
}
//Aaaand teleport it
var map = Transform(uid).MapUid;
if (TryComp<CP14DemiplaneComponent>(map, out var demiplan))
{
@@ -101,7 +107,6 @@ public sealed partial class CP14DemiplaneTravelingSystem : EntitySystem
private void RadiusMapInit(Entity<CP14DemiplaneRadiusTimedPasswayComponent> radiusPassWay, ref MapInitEvent args)
{
radiusPassWay.Comp.NextTimeTeleport = _timing.CurTime + radiusPassWay.Comp.Delay;
//Popup caution here
}
private void OnOpenRiftInteractDoAfter(Entity<CP14DemiplaneRiftOpenedComponent> passWay, ref CP14DemiplanPasswayUseDoAfter args)

View File

@@ -1,176 +0,0 @@
using System.Numerics;
using Content.Server._CP14.Footprints.Components;
using Content.Server.Decals;
using Content.Shared._CP14.Decals;
using Content.Shared.DoAfter;
using Content.Shared.Fluids;
using Content.Shared.Fluids.Components;
using Content.Shared.Interaction;
using Content.Shared.Inventory.Events;
using Content.Shared.Maps;
using Robust.Server.GameObjects;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Events;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.Footprints;
public sealed class CP14FootprintsSystem : EntitySystem
{
[Dependency] private readonly DecalSystem _decal = default!;
[Dependency] private readonly SharedMapSystem _maps = default!;
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<Components.CP14FootprintTrailerComponent, MoveEvent>(OnTrailerMove);
SubscribeLocalEvent<Components.CP14FootprintTrailerComponent, StartCollideEvent>(OnTrailerCollide);
SubscribeLocalEvent<CP14FootprintHolderComponent, GotEquippedEvent>(OnHolderEquipped);
SubscribeLocalEvent<CP14FootprintHolderComponent, GotUnequippedEvent>(OnHolderUnequipped);
SubscribeLocalEvent<CP14DecalCleanerComponent, AfterInteractEvent>(OnAfterInteract);
SubscribeLocalEvent<CP14DecalCleanerComponent, CP14DecalCleanerDoAfterEvent>(OnCleanDoAfter);
}
private void OnCleanDoAfter(Entity<CP14DecalCleanerComponent> ent, ref CP14DecalCleanerDoAfterEvent args)
{
if (args.Cancelled || args.Handled)
return;
var gridUid = Transform(ent).GridUid;
if (gridUid is null)
return;
if (!TryComp<MapGridComponent>(gridUid, out var map))
return;
var coord = EntityManager.GetCoordinates(args.ClickLocation);
_audio.PlayPvs(ent.Comp.Sound, coord);
SpawnAtPosition(ent.Comp.SpawnEffect, coord);
var oldDecals = _decal.GetDecalsInRange(gridUid.Value, args.ClickLocation.Position, ent.Comp.Range);
foreach (var (id, decal) in oldDecals)
{
if (decal.Cleanable)
_decal.RemoveDecal(gridUid.Value, id);
}
args.Handled = true;
}
private void OnAfterInteract(Entity<CP14DecalCleanerComponent> ent, ref AfterInteractEvent args)
{
if (!args.CanReach && !args.Handled)
return;
var doAfter = new DoAfterArgs(EntityManager,
args.User,
ent.Comp.Delay,
new CP14DecalCleanerDoAfterEvent(EntityManager.GetNetCoordinates(args.ClickLocation)),
ent)
{
BreakOnMove = true,
BreakOnDamage = true,
NeedHand = true,
};
_doAfter.TryStartDoAfter(doAfter);
args.Handled = true;
}
private void OnHolderUnequipped(Entity<CP14FootprintHolderComponent> ent, ref GotUnequippedEvent args)
{
if (!TryComp<Components.CP14FootprintTrailerComponent>(args.Equipee, out var trailer))
return;
trailer.holder = null;
if (TryComp<CP14FootprintHolderComponent>(args.Equipee, out var selfHolder))
{
trailer.holder = selfHolder;
}
}
private void OnHolderEquipped(Entity<CP14FootprintHolderComponent> ent, ref GotEquippedEvent args)
{
if (!TryComp<Components.CP14FootprintTrailerComponent>(args.Equipee, out var trailer))
return;
trailer.holder = ent.Comp;
}
private void OnTrailerCollide(Entity<Components.CP14FootprintTrailerComponent> ent, ref StartCollideEvent args)
{
if (ent.Comp.holder is null)
return;
var footprint = ent.Comp.holder;
if (!TryComp<PuddleComponent>(args.OtherEntity, out var puddle))
return;
if (puddle.Solution is null)
return;
var sol = puddle.Solution;
var splittedSol = sol.Value.Comp.Solution.SplitSolutionWithout(footprint.PickSolution, SharedPuddleSystem.EvaporationReagents);
if (splittedSol.Volume > 0)
UpdateFootprint(footprint, splittedSol.GetColor(_proto));
}
private void UpdateFootprint(CP14FootprintHolderComponent comp, Color color)
{
comp.DecalColor = color;
comp.Intensity = 1f;
}
private void OnTrailerMove(Entity<Components.CP14FootprintTrailerComponent> ent, ref MoveEvent args)
{
if (ent.Comp.holder is null)
return;
var footprint = ent.Comp.holder;
var distance = Vector2.Distance(args.OldPosition.Position, args.NewPosition.Position);
footprint.DistanceTraveled += distance;
if (footprint.DistanceTraveled < footprint.DecalDistance)
return;
footprint.DistanceTraveled = 0f;
var xform = Transform(ent);
if (!TryComp<MapGridComponent>(xform.GridUid, out var mapGrid))
return;
var tileRef = _maps.GetTileRef(xform.GridUid.Value, mapGrid, xform.Coordinates);
var tileDef = (ContentTileDefinition)_tileDefManager[tileRef.Tile.TypeId];
if (tileDef.Weather && tileDef.Color is not null)
{
UpdateFootprint(footprint, tileDef.Color.Value);
return;
}
if (footprint.Intensity <= 0)
return;
_decal.TryAddDecal(footprint.DecalProto,
xform.Coordinates.Offset(new Vector2(-0.5f, -0.5f)),
out var decal,
footprint.DecalColor.WithAlpha(footprint.Intensity),
xform.LocalRotation,
cleanable: true);
footprint.Intensity = MathF.Max(0, footprint.Intensity - footprint.DistanceIntensityCost);
}
}

View File

@@ -1,26 +0,0 @@
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.Footprints.Components;
/// <summary>
/// allows you to remove cleanable decals from tiles with a short delay.
/// </summary>
[RegisterComponent, Access(typeof(CP14FootprintsSystem))]
public sealed partial class CP14DecalCleanerComponent : Component
{
[DataField]
public SoundSpecifier Sound = new SoundCollectionSpecifier("CP14Broom")
{
Params = AudioParams.Default.WithVariation(0.2f),
};
[DataField]
public EntProtoId? SpawnEffect = "CP14DustEffect";
[DataField]
public float Range = 1.2f;
[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(0.75f);
}

View File

@@ -1,33 +0,0 @@
using Content.Shared.Decals;
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.Footprints.Components;
/// <summary>
/// stores the type of footprints and their settings.
/// </summary>
[RegisterComponent, Access(typeof(CP14FootprintsSystem))]
public sealed partial class CP14FootprintHolderComponent : Component
{
[DataField]
public ProtoId<DecalPrototype> DecalProto = "CP14FootprintsBoots";
[DataField]
public float DecalDistance = 1f;
[DataField]
public float DistanceTraveled = 0f;
[DataField]
public Color DecalColor = Color.White;
[DataField]
public float Intensity = 0f;
[DataField]
public FixedPoint2 PickSolution = 1f;
[DataField]
public float DistanceIntensityCost = 0.2f;
}

View File

@@ -1,14 +0,0 @@
namespace Content.Server._CP14.Footprints.Components;
/// <summary>
/// allows an entity to leave footprints on the tiles
/// </summary>
[RegisterComponent, Access(typeof(CP14FootprintsSystem))]
public sealed partial class CP14FootprintTrailerComponent : Component
{
/// <summary>
/// Source and type of footprint
/// </summary>
[DataField]
public CP14FootprintHolderComponent? holder = null;
}

View File

@@ -0,0 +1,6 @@
namespace Content.Server._CP14.Lighthouse;
[RegisterComponent]
public sealed partial class CP14LighthouseComponent : Component
{
}

View File

@@ -0,0 +1,23 @@
using Robust.Server.GameStates;
namespace Content.Server._CP14.Lighthouse;
public sealed partial class CP14LighthouseSystem : EntitySystem
{
[Dependency] private readonly PvsOverrideSystem _pvs = default!;
public override void Initialize()
{
SubscribeLocalEvent<CP14LighthouseComponent, ComponentStartup>(OnLighthouseStartup);
SubscribeLocalEvent<CP14LighthouseComponent, ComponentShutdown>(OnLighthouseShutdown);
}
private void OnLighthouseShutdown(Entity<CP14LighthouseComponent> ent, ref ComponentShutdown args)
{
_pvs.RemoveGlobalOverride(ent);
}
private void OnLighthouseStartup(Entity<CP14LighthouseComponent> ent, ref ComponentStartup args)
{
_pvs.AddGlobalOverride(ent);
}
}

View File

@@ -0,0 +1,15 @@
using Content.Shared._CP14.LockKey;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.LockKey;
[RegisterComponent]
public sealed partial class CP14AbstractKeyComponent : Component
{
[DataField(required: true)]
public ProtoId<CP14LockGroupPrototype> Group = default;
[DataField]
public bool DeleteOnFailure = true;
}

View File

@@ -0,0 +1,67 @@
using Content.Server.Station.Events;
using Content.Shared._CP14.LockKey;
using Content.Shared._CP14.LockKey.Components;
using Content.Shared.Station.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;
namespace Content.Server._CP14.LockKey;
public sealed partial class CP14KeyDistributionSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly CP14KeyholeGenerationSystem _keyGeneration = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CP14AbstractKeyComponent, MapInitEvent>(OnMapInit);
}
private void OnMapInit(Entity<CP14AbstractKeyComponent> ent, ref MapInitEvent args)
{
if (!TrySetShape(ent) && ent.Comp.DeleteOnFailure)
QueueDel(ent);
}
private bool TrySetShape(Entity<CP14AbstractKeyComponent> ent)
{
var grid = Transform(ent).GridUid;
if (grid is null)
return false;
if (!TryComp<CP14KeyComponent>(ent, out var key))
return false;
if (!TryComp<StationMemberComponent>(grid.Value, out var member))
return false;
if (!TryComp<CP14StationKeyDistributionComponent>(member.Station, out var distribution))
return false;
var keysList = new List<ProtoId<CP14LockTypePrototype>>(distribution.Keys);
while (keysList.Count > 0)
{
var randomIndex = _random.Next(keysList.Count);
var keyA = keysList[randomIndex];
var indexedKey = _proto.Index(keyA);
if (indexedKey.Group != ent.Comp.Group)
{
keysList.RemoveAt(randomIndex);
continue;
}
_keyGeneration.SetShape((ent, key), indexedKey);
distribution.Keys.Remove(indexedKey);
return true;
}
return false;
}
}

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