Upstream stable sync (#1708)
* moth displacement map fixes
* Make VendingMachineInventoryEntry a data definition for post-init savegrid (#38406)
fix: make VendingMachineInventoryEntry a data definition
* Automatic changelog update
* Exo - Major Sec changes, and more! (#39295)
* Automatic changelog update
* Fix variantize command not respecting tile rotation (#39314)
Oopsiedoodle
* Renames slugcat jelly-donuts to scurret jelly-donuts (#39308)
* renames slugcat jelly-donuts to scurret jelly-donuts
* renames slugcat jelly-donuts to scurret jelly-donuts
* renames slugcat jelly-donuts to scurret jelly-donuts
* missing end of file new line
---------
Co-authored-by: Arcane-Waffle <FR_Waffle@proton.me>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Predict EmitterSystem ExamineEvent and GetVerbsEvent (#39318)
* ididathing.exe
* commit
* cleanup
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Predict ExamineEvent for CryoPodSystem. (#39322)
commit
* Fix tabletop grids rarely spawning on top of another (#39327)
* fix: fix off-by-one for tabletop map positions
Ulam spirals start at 1, not 0.
* fix: make the ulam spiral a ulam spiral
* Automatic changelog update
* Add test of `StaminaComponent` crit vs animation thresholds (#39249)
Add test of StaminaComponent crit vs animation thresholds
* HumanoidCharacterProfileFix (#39333)
* Automatic changelog update
* Fix StoreTests EventBus usage (#38489)
Fix split off from #37349 to avoid needing to sync the content/engine PRs.
* Don't purge note buffer when starting/switching MIDI songs (#39335)
Stop stuck notes on remote when changing MIDI song
* Berry Delight (#38881)
* Berry delight
* Uncook the YAML
* Move stuff in meal_recipes
* BERRY DELIGHT IS INEVITABLE
* Automatic changelog update
* Fix horizontal space men in replays (#39338)
* Fix horizontal space men in replays
Visualizer should not bail if data unavailable.
* Update Content.Client/Rotation/RotationVisualizerSystem.cs
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Fix ActionsSystem.IsCooldownActive always returning false if curTime is null (#39329)
* Make dirt non-compressible (#39220)
This sets the new rsic: false flag in dirt.rsi. One of the interior PNGs is directly accessed by a tile definition, which would otherwise cause a game startup failure with the new packaging improvements: c4dff678a9
* Predict anomaly synchronizer (#39321)
* predict anomaly synchronizer
* pvs
* lambda
* Update Resources/Locale/en-US/anomaly/anomaly.ftl
---------
Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com>
* parrotMemory is onGetVerbs now in shared (#39341)
* parrotMemory is onGetVerbs now in shared
* code review
* code review popup on client rename parrotMemoryComponent
* code rev create client system
* forgot usings
* is server now
* Fix rotate verbs not being predicted (#38165)
* Fix rotate verbs not being predicted
* fixes
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Automatic changelog update
* Update Credits (#39343)
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
* Advanced Clowning Module (#35797)
* pAIs can now accept keys, but can't talk in said channels
* added dummy module
* added adv clown module alongside projector
* holopeel & projector sprite added, it's destroyable too
* added experimental pie cannon
* exp pie thrower throws pies, added tool icon, added bananium horn
* removed the weird pAI changes, my bad!
* okay NOW the pAI stuff is all gone
* added icon, recipe, renamed tech for unlocking
* removed bananium horn
* Added in-hand sprites, credited to TiniestShark. Changed holopeel projector description to let the user know it recharges over time.
* change bagel genpop biocube fabricator into biogenerator (#39313)
* Hardsuit helmet text fix + CBurn Vox Fix (#39345)
* text fix and vox helm fix
* oop one line
* Localize Refund Button (#39346)
* Localize Refund Button
* Requested changes
* Make wallmount screen, telescreen, and signal timer destructible (#39340)
* make wallmount screen destructible
* louder
* fix indent
* fix indent
* Trigger Refactor (#39034)
* Xenoborgs part 4 (#36935)
Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Co-authored-by: Quantum-cross <7065792+Quantum-cross@users.noreply.github.com>
Co-authored-by: pathetic meowmeow <uhhadd@gmail.com>
Co-authored-by: Southbridge <7013162+southbridge-fur@users.noreply.github.com>
Co-authored-by: WarPigeon <DaedalusTheGamer@gmail.com>
Co-authored-by: Kowlin <git@wyvern.blue>
Co-authored-by: ScarKy0 <scarky0@onet.eu>
* fix: auto-update mailing unit + gas canister UIs on state (#39289)
* fix: auto-update mailing unit + gas canister UIs
* fix: make FollowerComponent auto handle state
* refactor: kill AfterAutoHandleState for Follower
* flakeops
* Updated syndicate throwing knives description (#39374)
Co-authored-by: seanpimble <149889301+seanpimble@users.noreply.github.com>
* Automatic changelog update
* Revert "Fix bug with pipe color" (#39135)
* Move `HeadstandComponent` to Shared (#39377)
Move HeadstandComponent to Shared
* Fix head mappers codeowners (#39378)
webedit ops codeowners
* Fix vox inhand displacements (#38507)
fix
* Add Offset Canes + Trinket Canes Group (#39272)
* Added offset cane
* Added offset cane colors
* Added canes to the trinkets menu
* added color to names instead of suffix
* removes some stripes from the mime cane icon
* update file organization
* standard -> standard.rsi, stop making commits at nearly 3 in the morning.
* updated comment to be more explicit in what doesnt work
* Cane refactor :godo:
* git makes me very upset sometimes (fixed cane yaml)
* wooden->wood
* apparently this didnt push
* Standardize comments
* Removed comment
* Removed comment
* Adds red accents to mime cane
* Indent fixes
* Automatic changelog update
* add: air alarm scrubber select all gases button (#39296)
* add select all gases button
* now make it work
* localize
* refactor
* remove redundant Orientation
Co-authored-by: Perry Fraser <perryprog@users.noreply.github.com>
* remove useless HorizontalExpand
Co-authored-by: Perry Fraser <perryprog@users.noreply.github.com>
* add nice newline
Co-authored-by: Perry Fraser <perryprog@users.noreply.github.com>
* deduplicate Enum.GetValues<Gas> usage
---------
Co-authored-by: Perry Fraser <perryprog@users.noreply.github.com>
* Automatic changelog update
* Fix ATS Anchor (#39389)
* fix: hide timer trigger's cycle time verb if DelayOptions is empty (#39388)
fix: hide cycle time verb if DelayOptions is empty
* Automatic changelog update
* Removes ItemToggle from Cryo Pods to prevent a latent event ordering bug (#39197)
Removes ItemToggle component from the cryo pod as it was useless and risked a latent verb order bug
* remove space from Sleeping Carp.png (#39369)
* Rename Sleeping Carp.png to SleepingCarp.png
* Update meta.json
* localization support to air alarms, wire panels and more (#39307)
* Add localization to the air alarms, wire panels, network configurator list menu and loadout window
* delete unused
* redo gas localization, delete unused
* removed the extra key
* Moved and renamed air-alarm-ui-thresholds-gas-name
* Moved localization to the XAML
* Use existing strings for gas names
* it just works
* Rename _atmosphereSystem in ScrubberControl.xaml.cs
_atmosphereSystem -> atmosphereSystem
* Rename _atmosphereSystem in SensorInfo.xaml.cs
_atmosphereSystem -> atmosphereSystem
* Fixed Issues with Screens and Station Maps (#39393)
* Predict warp point location examines. (#39402)
commit
* Reduced SalvageStructureComponent to atoms. (#39400)
* commit
* whoopsie daisy
* Update SpawnSalvageMissionJob.cs
* Update SpawnSalvageMissionJob.cs
* cleanup
* Predict Nav Beacon Examine (#39408)
* commit
* Update Content.Shared/Pinpointer/SharedNavMapSystem.cs
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Add guard to unbuckling to help it to not act upon terminating entities (#39410)
* Add guard to unbuckling to help it to not act upon terminating entities
* Refactor guard for unbuckling
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Revert "Refactor guard for unbuckling"
This reverts commit bf975fbd6f5cfac45324a3d5d74e592ad17ad291.
---------
Co-authored-by: Luxeator <Luxeator>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Automatic changelog update
* fix: properly respect AllowRepeatedMorphs (#39411)
* fix: properly respect AllowRepeatedMorphs
* feat: add IgnoreAllowRepeatedMorphs
* Predict cryopods (#39385)
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
* feat: properly perform predicted porta pottys (fix toilet prediction) (#39394)
* Remove redundant return statement in InventoryUIController (#39381)
* Update attributions for lightning audiofiles (#39395)
* Predict PickRandom verb (#39326)
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
* Adds infinite debug power APC, substation, SMES (#39317)
* make debug power infinite
* demarcate infinite and empty debug power
* fix duplicate ID
* change infinite suffix to autorecharge
* Status effects disable light occluding (1-line PR) (#39418)
Update StatusEffectsSystem.cs
* Move scale command to content and turn it into a toolshed command (#39349)
* scale command
* fix namespaces
* MessyDrinker for dogs (#38852)
* Automatic changelog update
* Update RT to 266.0.0
* Predict EMP Examine (#39419)
* another one bites the dust
* Update Content.Shared/Emp/SharedEmpSystem.cs
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Predict base and damage examines of cartridge ammo. (#39401)
* commit
* requested changes +
* fix DoAfter DistanceThreshold (#39276)
* Automatic changelog update
* convert dwarfs to use ScaleVisualsComponent (#39422)
* Move solution examine subscription from DrinkComponent to ExaminableSolutionComponent (#39362)
* initial it works
* clean it up
* yml
* datafield the LocIds
* move from the other branch
* no max vol on puddles and anoms
* closed
* Changes inspired by #39008
* small bug and more color range
* puddle changes and more examinable solutions
* lint
* small change
* requested changes
* un-delete
* tiny comment
* 1 less loc id in this world
* request and last second change
---------
Co-authored-by: iaada <iaada@users.noreply.github.com>
* Automatic changelog update
* Debody Food and Drink Systems, Combine Food and Drink into One System. (#39031)
* Shelve
* 22 file diff
* What if it was just better
* Hold that thought
* Near final Commit, then YAML hell
* 95% done with cs
* Working Commit
* Final Commit (Before reviews tear it apart and kill me)
* Add a really stupid comment.
* KILL
* EXPLODE TEST FAILS WITH MY MIND
* I hate it here
* TACTICAL NUCLEAR STRIKE
* Wait what the fuck was I doing?
* Comments
* Me when I'm stupid
* Food doesn't need solutions
* API improvements with some API weirdness
* Move non-API out of API
* Better comment
* Fixes and spelling mistakes
* Final fixes
* Final fixes for real...
* Kill food and drink localization files because I hate them.
* Water droplet fix
* Utensil fixes
* Fix verb priority (It should've been 2)
* A few minor localization fixes
* merge conflict and stuff
* MERGE CONFLICT NUCLEAR WAR!!!
* Cleanup
---------
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
* Fun with cardboard! (#37363)
* learning???
* made card walls work, then made game unlaunchable (:
* Still broken, added notes that I thought of while in bed
* wall, door, table and chair are now bare min functional, yay
* learnt why not to web edit...
* added floors, walls and floors fully complete
* added swords, shields, armour, helmets and arrows
* added funny sound and cleanup small issues
* cleanup
* cleanup
* credited myself
* card to cardboard
* fixed licence issue and meta thingy
* adjusted arrow stam-damage
* made card carpets more regular
* simplified sprite, reduced stam damage
* formatting fixes
---------
Co-authored-by: beck-thompson <beck314159@hotmail.com>
* Automatic changelog update
* add scale:multiplyvector toolshed command (#39424)
* Automatic changelog update
* fix repeated scale visuals removal/ensuring (#39432)
* Miscellaneous Body Decoupling (#38958)
* Turn some implants into triggers (#39364)
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
* Changeling devour and transform (#34002)
* Initial:
Create Devour componentry, preliminary identity storage and the systems
for Devouring
* I have genuinely no idea what i'm doing
- added the radial menu, it has nothing in it.
- trying to get it to populate. the event under the event is broken,
i don't know why, but apparently it's not typed right
- Added a placeholder transform
- oh also fixed up some devour stuff and moved some things around.
* Holey moley, Transform, better devour, oh my!
- Move DnaComponent into Shared because we need it for the DNA cloning
- Make Transform MOSTLY work on the LAST identity devoured.
- Fix some issues on devour that involved prediction, canceling and
Damage exeucting (Thanks Plykiya for pointing out AttemptFrequency!)
* Proper tail stealing and Damage modifier attempt
Add check to add a wagging component on the Changeling if the victim's
species Prototype had one.
attempt to add the Damage mitigation check
* MAJOR CLEANUP AND FIXES AUGH 3 DAYS!!!
- Nullspaced a clone of a victim
- fix audio using server virtualized Pvs (i hate this)
- fix the mispredicted doafters
- Clean up a wholelotta code
- utilize clone systems to clone appearances
- Move CloneAppearance from server to shared So we can actually access
it
* Examine stuff, more cleanup, Jumpsuit ripping
- make rotting prevent the action
- Add ripping of clothing (guh why is it also server)
- add some System stuff for pushing husked corpse inspection
- clean up more badcode
* Doing things properly, UI sorta kinda works.
- Utilize Relayed events for Devour checking
- Get a UI that partially works, Says the name of identities, doesn't
show their looks
- Make use of the New Dynamic BUI assignment
- commit the sin of no client prediction cause nullspace entities aren't
networked
* Got an entity for the Frontend transform
Issue with the looks
* Stick a camera into a fake mobs forehead
- Get the UI to see the net entity in pause space by using a
ViewSubscriber to get the Pvs from the initially stored identity entity
- Remove all the other parts used to try to get this to work before hand
* Raaaaadiallllllls also fix protection coefficents
- Change FancyWindow to Radial
- Fix Issue where coeffeient checking was the wrong way round
* absolutely massive cleanup, no more camera in mobs
- cleaned up event variables that are not needed
- Removed the use of a Pause space and go back to Nullspace usage
- use a PvsOverride rather than ViewSharing
- Remove old commented out code and Lots of unused code
* Fix "Ui elements" dying on the screen
- some minor cleanup
- don't start the entities that get cloned
* ftl, cleanup, and fixing missing transform details
- add replace functionality to TypingIndicatorSystem and
BodyEmotesSystem
- add placeholder sounds and functions to TransformBodyEmotes
- add extra Pvs handling for later use
- attributions for the funny straw sound
- Sound collections for all of the sounds
- various cleanups
* Some extra cleanup
* Fix some false assumptions about TypingIndicator
- Bubbles now transfer on spawned humans rather than used humans
- Clean up YET MORE CODE
- make it so you can't eat yourself
* Oooprs, forgot to add a Husked Corpse Loc
* Missing period in the husked corpse loc
* bad devour windup placeholder
* Husking and WIP Lungs
- Husking now will be prevented from Revival fully and will change
the appearance of players
* Add finalized Sprites for actions and final meta
- add devour on and off sprites
- add transform action sprite
- Add Armblade sprite for future use
- Credit obscenelytinyshark for the sprites <3
* Remove ling lungs, Entity<> everything
- Remove the ling lungs stuff for now... body system is overly
complicated, makes my head hurt
- Switch every method to use Entity<> from Uid, Comp format
* cleanup, admin logging, WIP Roles
* Admin verb, Roundstart, gamerule stuff
- add a Admin verb to make Changelingification easy!
- Add game rule stuff for admin verb and to tell the hapless
goober how to be a changeling... sorta
- clean up parts to make VV easy... USE THE VERB!!
* Armor Coefficent Check
- Remove bespoke changeling armor check and replace it
with a generic armor coefficient query.
* move to UnrevivableComponent instead of husked
- Move UnrevivableComponent to shared
- add Analyzable and ReasonMessage to UnrevivableComponent
to give granular control of the message and whether or not it shows up
in the analyzer
- remove the check for HuskedComponent in DefibrillatorSystem
* aaaaaaa CopyComp
- Some cleanup
- make Vocal system shared
- make VocalSystem Not make more Actions than it needs
- Use some code from ChameleonProjector so we can copy components
- partially ungod method the Transform system
* Cleanup, Moving more things to CopyComp
- TransformBodyEmotes now uses CopyComp (it's a server component so i
need to tell the server to deal with it
- TypingIndicatorComponent also now uses CopyComp
- cleaned up old, now unused "replace" methods in favor of CopyComp
- BodyEmotesSystem now has a publically accessable LoadSounds to deal
with the same problem Screaming had
* WIP
* Devour Windup noise, ForensicsSystem cleanup
* Revert VocalSystem Changes
- Reverted Moving VocalSystem to shared, copy comp acomplishes it
- added component.ScreamActionEntity = null; for copy comp
* cleanup unneeded comments
* revert an accidental line removal
* Remove duplicate SharedHumanoidAppearanceSystem
* Cleanup Typo's and import Forensics components for Dna
* Some more forensics calls
* cleanup use CopyComp for now until CopyComps
* CR cleanup
* Undo some SharedHumanoidAppearanceSystem changes
* Confound these spaces
* Some Copycomp stuff and fixing some PVS override
* use the proper TryCopyComps that are merged
* Change TransformMenu with RadialWithSector
* All sounds done, Fix lack of typing indicator issue
* Updated attributions to include used sound authors
* some ftl typos and mind_role text issue
* DNA, Screaming, appearance, grammar, wagging
- reduced all of the above using ApplyComponentChanges
- Issue still remains with bodyEmotes sticking around in the UI
* Fix UI stuff, partials, entprotoid, good practices
- bunch of partials added
- UI now has a predicted message
- EntProtoID in the admin verb
- RipClothing now uses Entity<ButcherableComponent>
- husking is now optional (off by default) for testing/till we have
hivemind/when we figure out what were doing with devour
- remove TransformGrammarSet
* More CR stuff and documentation
- Make TargetIsProtected less of a meme, with a prototype
set of DamageTypes to check
- Documenation everywhere
- Move DevourEvents into its own file
* Predicted sounds and fix the comp clone list
- Made all start and stop sounds shared
- Split out the rest of the events and UI stuff into subfiles
- Fixed some Clone comp list issues where comments had -'s causing them
to be read incorrectly
* Damage cap check, Identity Shutdown cleanup, cleanup
* Sound stuff (but actually this time)
* Missed documentation
* Missed Documentation and a EntProtoId
* Remove unused dependency
* Remove a nullcheck
* Some dummy minplayers
* CR - Husked now uses a rem/ensure
* Update Actions in the Prototype
* Fixup mindswap handover
- cleanup and handover PVS on mindswap
* Fixup Missing meta from accidental "Take-theirs"
* Add the Armblade to the roundstart-role
* Cleanup, CR (everything but the UI and renames)
* missed a spot
* missed some more whitespace
* Renames
* Primary constructor and a space in these trying times
* User interface stuff for Slime transformation
* popup prediction
* Ling devour no longer makes duplicate identities
- added a key to identities to the original victim
- Add some extra clone settings
* add guard statements to OnClones
* SentOnlyToOwner additions
* fix for sound stoppage error
* Move Organ deleter into soon to be atomized husk
* clone event inventory
* mono sounds
* lower sound volume
* Fix networked sound warning
* Clone comps thing
* review
* attributions
* Fix clobbered changes
* I'm gonna weh out
- whole bunch of CR changes
* fix some very buggy git
* okay its fixed
* address most review points
* fix inventory
* we hate entityuids
* fix test and more cleanup
* move this
* fix more stuff
* fix validation and rootable
* Remove Quickswitch due to some UI quirks
* oops left out some better explanation
* remove dangling LastConsumed component fields
* fix test fail
* try this
* cleanup cloning subscriptions, add movement speed modifier
* fix slime storage
* fix cloning setting inheritance
* Add session information to transform admin logs
* slay the integration test hydra
* dwarf size
* more volume tweaks
* comments
* improve comments and unpredict deletion due to errors when shutting down the server
* fix displancement cloning
---------
Co-authored-by: ScarKy0 <scarky0@onet.eu>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Fix inventory flickering and missing InventoryTemplateUpdated event (#39379)
* fix flickering
* move InitClothing
* fix this
* Automatic changelog update
* Fix showvalue Ui for melee weapons (#38703)
Co-authored-by: Perry Fraser <perryprog@users.noreply.github.com>
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
* docs: update comment on config saving in tests (#39438)
* Ingestion Bugfixes (#39436)
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
* Bloonion mutation (#33375)
* Automatic changelog update
* Fix title2.ogg attribution (#39435)
Co-authored-by: kait <kait@azumanga.gay>
* Resized baseball bats to be more realistic (#38392)
* Resized baseball bats to be more realistic
* Added new vertical icon for the baseball bat & incomplete variant, sprites by TiniestShark
* Added requested changes
* Added suggested changes for the incomplete sprite
* Automatic changelog update
* Fix Ingestion Localization Pop-ups (#39437)
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
Co-authored-by: ScarKy0 <scarky0@onet.eu>
* place stored changeling identities next to each other (#39452)
* Fix changeling typing indicator (#39454)
init
* give paused maps from polymorph and cryostorage a name (#39453)
* Automatic changelog update
* fixes items with complex shapes failing to insert sometimes (#38896)
* fixes item insertion bug
fixes bug where items with complex shapes would fail to insert if the item's StoredRotation wasn't a right angle
* independence from StoredRotation
* Automatic changelog update
* Add changeling briefing sound (#39465)
* init
* guh
* Disable changeling fixture cloning (#39467)
init
* Move some Station methods into shared (#38976)
* make objectives use yml defined mind filters (#36030)
* add MindHasRole whitelist overload
* add mind filters framework
* add different mind filters and pools
* update traitor stuff to use mind filters
* line
* don't duplicate kill objectives
* g
* gs
---------
Co-authored-by: deltanedas <@deltanedas:kde.org>
Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Co-authored-by: ScarKy0 <scarky0@onet.eu>
Co-authored-by: SlamBamActionman <slambamactionman@gmail.com>
* Sentry turrets - Part 8: AI notifications (#35277)
* Automatic changelog update
* Starting glasses for Captain and HoP (#35531)
* Automatic changelog update
* fix: fix emote wheel icons (#39481)
* Automatic changelog update
* Remove NamesGolem (#39478)
* deleted golem.ftl which contained golem names
* deleted golem.yml that went along with golem.ftl
* Cleanup Base food and drink a little (#39485)
Edible base prototype convention compliance
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
* Fix Whoopie Cushions from lagging the game. (#39194)
* Fix bar and base signs (#39487)
sorry
* Buttons are now Free-placeable (again) (#39425)
Fixed buttons
* fix mind role filter (#39499)
* Fix: Water Bottles Verb Priority and Prediction (#39482)
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
* Network StationMember properly (#39509)
* Mapping - Box station - Tie the RD's disposal bin to the disposals system. (#39507)
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
* Automatic changelog update
* Update Credits (#39512)
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
* Crawling Fixes 1: Dragons and Borgs can't do the worm. (#39084)
* Init Commit
* Remove unused code, fix stun visuals bug
* Update Content.Shared/Stunnable/SharedStunSystem.cs
* Some initial changes
* first batch of changes
* Commit
* One line cleanup
* KnockdownStatusEffect ain't worth it.
* Fix 2 bugs
* Fixes
* Remove that actually,
* Commit
* Better solution
* Alright final commit I think
* Add better remarks
* How the fuck did this not get pushed???
* Wait no why was my ryder trying to push that??? I didn't make that change! DON'T DO THAT!!!
* Review
* Don't log that
---------
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
* Automatic changelog update
* Add voice locks to various hidden syndicate items (#39310)
* Automatic changelog update
* Fire stacks trigger (#39530)
* Simple as
* whoops
* not gonna work
* chopped
* missed something
* Better name
* formatting
---------
Co-authored-by: iaada <iaada@users.noreply.github.com>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Status Effect Alerts and Time Bugfixes (#39529)
* Bugefix
* Clean up
---------
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
* Adds rare Hamlet variant: Fragile Hamlet (#39531)
* slippery gib hamlet
* add suffix for easier admeme
* address review
* increase odds
* parent MobHamsterHamlet, predicted emitsound
---------
Co-authored-by: Jessica M <jessica@maybe.sh>
* Automatic changelog update
* Trigger on round end (#39545)
* works if it works
* small rewording
---------
Co-authored-by: iaada <iaada@users.noreply.github.com>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* fix: reform dionas via SpawnNextToOrDrop (#39505)
* Automatic changelog update
* Actions examine (#39558)
* Predict suitsensor system (#39325)
* adwadsdwasadwas
* dev
* fix
* review
* some more cleanup
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Oasis: Add atmos network monitor (#39331)
* Automatic changelog update
* Base changeling objective(s) (#39562)
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Better robotics console (#38023)
* Automatic changelog update
* ExtinguishOnTrigger and TriggerOnInteractHand (#39537)
* simplely one commit
* simplelly two commit
* requested changes
---------
Co-authored-by: iaada <iaada@users.noreply.github.com>
* [HOTFIX] Stop players from clipping through Windoors (#39564)
* Don't have standing state edit soft fixtures?
* Bugfix
* Cherry pick acquired
---------
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
* Reduce LevelOfParallelism to 2 for integration tests (#39566)
less paralelliism
* [HOTFIX] Stop players from clipping through Windoors (#39564)
* Don't have standing state edit soft fixtures?
* Bugfix
* Cherry pick acquired
---------
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
* Reduce LevelOfParallelism to 2 for integration tests (#39566)
less paralelliism
* Predict PoweredLights (#36541)
* Move PoweredLight to shared
* Predict the rest of the owl
* reacher
* compinit & anim
* Fix names
* Revert this?
* Fix these
* chicken drummies
* deita
* Fix
* review
* fix
* fixes
* fix PVS weirdness
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Automatic changelog update
* Fix ReagentQuantity Equality check (#39574)
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
* feat: make ReagentId hash by value (#39494)
* Fix antag objective assignment (again) (#39565)
init
* Fix dock radar colours (#38942)
* Fix docking colours
* Add comments and fallback
* Better comments!
* Slightly shorten examine text for splashing a solution with a melee attack (#39428)
smaller text.
Co-authored-by: iaada <iaada@users.noreply.github.com>
* Borg hands & hand whitelisting (#38668)
* Borg hands & hand whitelisting
* yaml linted
* yaml linted (x2)
* yaml linted (x3)
* my storage tests so pass
* no need for SetCount
* ok new stuff you can get fixed too
* oops
* staque
* what if we addressed feedback
* my place so holder
* what if we addresesd feedback
* what if i did it correctly
* terminating or deleted
* Automatic changelog update
* fix: fix lights not always enabling correctly (#39585)
* Automatic changelog update
* RandomChance trigger condition (#39543)
* branch names don't matter anyway
* commits are a window to the soul
* requested change
* also requested
* ship it
* remove key
---------
Co-authored-by: iaada <iaada@users.noreply.github.com>
* Fix: Break do_after if target/tool becomes inaccessible (#35079)
* Predict GetVerbsEvent in PowerSwitchableSystem (#39589)
* Prediction
* Update
* Move mind role components to shared (#39606)
* Disable the lock/unlock verb if we can't do that (#39605)
* Fix
* Update
* StaminaDamageOnTriggerComponent (#39607)
* InflictStaminaOnTriggerSystem
Surprised this wasn't done alongside the damage one.
* Correct docstring
* Moar docstring changes!!!
* Resolve PR comment
* a
* Update Content.Shared/Trigger/Systems/StaminaDamageOnTriggerSystem.cs
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Weapon Resizing (#36473)
* Automatic changelog update
* Compact Security Jetpacks (#39569)
Made security jetpacks functionally identical to mini jetpacks.
Signed-off-by: Nox38 <nebulousnox38@gmail.com>
* Revert "Fix: Break do_after if target/tool becomes inaccessible" (#39617)
* fix lightbulb color (#39623)
* Automatic changelog update
* In Memoriam - Memorializing those who've passed within the SS13+SS14 community (#39621)
In Memoriam - adds a section to the credits memorializing those who've passed
* Automatic changelog update
* Add trigger-refactor components and systems: Batch 1 (#39391)
* Adds the following batch of trigger refactor components and their associated systems:
TriggerOnLand: LandEvent
TriggerOnExamined: ExaminedEvent
TriggerOnUnbuckle: UnbuckledEvent
TriggerOnBuckle: BuckledEvent
TriggerOnStrap: StrappedEvent
TriggerOnUnstrapped: UnstrappedEvent
* Removes unnecessary lines from comment
* Fix comment formatting, corrects grammar and increases comment clarity.
* adds last forgotten edit to comments
* Update Content.Shared/Trigger/Systems/TriggerOnStrappedOrBuckledSystem.cs
Removes unnecessary comments
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Content.Shared/Trigger/Components/Triggers/TriggerOnBuckledComponent.cs
Increases comment clarity
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Content.Shared/Trigger/Components/Triggers/TriggerOnExaminedComponent.cs
Increases comment clarity
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Content.Shared/Trigger/Components/Triggers/TriggerOnLandComponent.cs
Increases comment clarity
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Content.Shared/Trigger/Components/Triggers/TriggerOnStrappedComponent.cs
Increases comment clarity
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Content.Shared/Trigger/Components/Triggers/TriggerOnUnbuckledComponent.cs
Increases comment clarity
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Update Content.Shared/Trigger/Components/Triggers/TriggerOnUnstrappedComponent.cs
Increases comment clarity
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* refactored TriggerOnStrappedOrBuckledSystem.cs
removed TriggerOnExaminedSystem.cs and moved it into TriggerSystem.Interaction.cs
Changes currently untested, not sure how to make it so modders can change what method they want sending out the appropriate trigger key but want to save progress working on it and get feedback from maintainers
* Removed component which already exists as part of TriggerSystem.Interaction.cs
* Restores accidentally removed component
* Apply suggestions from code review
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
* Add myself to codeowners file (#39636)
* RemoveComponentsOnTrigger, ToggleComponentsOnTrigger (#39639)
* Rebalance advanced Brute chems, and more (#39472)
* Initial commit
* Update based on feedback
* Minor fix
* Update to match playtest
* Update reaction behavior and test to work; max temp is no longer an inclusive value.
* Revert "Update reaction behavior and test to work; max temp is no longer an inclusive value."
This reverts commit 2a2c4a17a623cc7ddc15b63d91a1b8b441e95cea.
* Incorporate heal values & OD for adv. chems from 39464, revert adv. brutes recipes
* Automatic changelog update
* Fix industrial reagent grinder bug, second attempt (#39690)
* fix recycler 3
* Update Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml
* unbreak StandingStateSystem
* Added "highly illegal" contraband to guidebook (#38176)
* Added extreme contraband to guidebook
* Extreme -> Highly Illegal
* Whoops, one-letter typo
* Fixed a capital letter while I'm here
* adapt codebase
* Update water_creation.yml
* Update water_creation.yml
* remove random food
* Refactor Food component to Edible in meal and cooking entities
Replaced the deprecated 'Food' component with the 'Edible' component in bowl, plate, and pie_pan YAML prototypes. Updated base cooking entity whitelist to include 'Edible' for compatibility. This change standardizes food consumption logic and improves maintainability.
---------
Signed-off-by: Nox38 <nebulousnox38@gmail.com>
Co-authored-by: Flareguy <woaj9999@outlook.com>
Co-authored-by: Perry Fraser <perryprog@users.noreply.github.com>
Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com>
Co-authored-by: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com>
Co-authored-by: Arcane-Waffle <denisliazhev@gmail.com>
Co-authored-by: Arcane-Waffle <FR_Waffle@proton.me>
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Co-authored-by: Kyle Tyo <36606155+VerinSenpai@users.noreply.github.com>
Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
Co-authored-by: Krosus777 <38509947+Krosus777@users.noreply.github.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
Co-authored-by: Hannah Giovanna Dawson <karakkaraz@gmail.com>
Co-authored-by: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com>
Co-authored-by: Token <56667933+TokenStyle@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: ThatGuyUSA <thatguyusa123@gmail.com>
Co-authored-by: qwerltaz <69696513+qwerltaz@users.noreply.github.com>
Co-authored-by: Tiniest Shark <head.rebel@yahoo.com>
Co-authored-by: Zeneganto <fantik8800@gmail.com>
Co-authored-by: Samuka-C <47865393+Samuka-C@users.noreply.github.com>
Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Co-authored-by: Quantum-cross <7065792+Quantum-cross@users.noreply.github.com>
Co-authored-by: pathetic meowmeow <uhhadd@gmail.com>
Co-authored-by: Southbridge <7013162+southbridge-fur@users.noreply.github.com>
Co-authored-by: WarPigeon <DaedalusTheGamer@gmail.com>
Co-authored-by: Kowlin <git@wyvern.blue>
Co-authored-by: ScarKy0 <scarky0@onet.eu>
Co-authored-by: alexalexmax <149889301+alexalexmax@users.noreply.github.com>
Co-authored-by: seanpimble <149889301+seanpimble@users.noreply.github.com>
Co-authored-by: Mora <46364955+TrixxedHeart@users.noreply.github.com>
Co-authored-by: Minemoder5000 <minemoder50000@gmail.com>
Co-authored-by: Marlyn <marlyn@marlyn.cloud>
Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com>
Co-authored-by: Ser11y <160628372+Ser1-1y@users.noreply.github.com>
Co-authored-by: Luxeator <derkerl1@gmail.com>
Co-authored-by: PGray <77597544+PGrayCS@users.noreply.github.com>
Co-authored-by: Serylis of Five <kasper.west-hansen+github@fivetail.dk>
Co-authored-by: K-Dynamic <20566341+K-Dynamic@users.noreply.github.com>
Co-authored-by: Myra <vasilis@pikachu.systems>
Co-authored-by: āda <ss.adasts@gmail.com>
Co-authored-by: iaada <iaada@users.noreply.github.com>
Co-authored-by: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com>
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
Co-authored-by: Tao <56692749+TaoNewt@users.noreply.github.com>
Co-authored-by: beck-thompson <beck314159@hotmail.com>
Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
Co-authored-by: poklj <compgeek223@gmail.com>
Co-authored-by: Thinbug <101073555+Thinbug0@users.noreply.github.com>
Co-authored-by: Stefano Pigozzi <me@steffo.eu>
Co-authored-by: kait <kait@azumanga.gay>
Co-authored-by: Kittygyat <202250949+Kittygyat@users.noreply.github.com>
Co-authored-by: lolman360 <22850904+lolman360@users.noreply.github.com>
Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: SlamBamActionman <slambamactionman@gmail.com>
Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com>
Co-authored-by: M87S <147015589+M87S@users.noreply.github.com>
Co-authored-by: kosticia <kosticia46@gmail.com>
Co-authored-by: Serylis of Five <stormy-git@stormweyr.dk>
Co-authored-by: beck-thompson <107373427+beck-thompson@users.noreply.github.com>
Co-authored-by: Jessica M <jessica@jessicamaybe.com>
Co-authored-by: Jessica M <jessica@maybe.sh>
Co-authored-by: Alex <firestar@firestar4.com>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: UpAndLeaves <92269094+Alpha-Two@users.noreply.github.com>
Co-authored-by: Winkarst-cpu <74284083+Winkarst-cpu@users.noreply.github.com>
Co-authored-by: Nox <nebulousnox38@gmail.com>
Co-authored-by: deathride58 <deathride58@users.noreply.github.com>
Co-authored-by: Studio Fae-Wilds <studio.faewilds@gmail.com>
Co-authored-by: Simon <63975668+Simyon264@users.noreply.github.com>
Co-authored-by: Errant <35878406+Errant-4@users.noreply.github.com>
Co-authored-by: Hitlinemoss <209321380+Hitlinemoss@users.noreply.github.com>
This commit is contained in:
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@@ -1,6 +1,2 @@
|
||||
# TheShuEd
|
||||
* @TheShuEd
|
||||
|
||||
# TornadoTechnology
|
||||
*.cs @Tornado-Technology
|
||||
*.xaml @Tornado-Technology
|
||||
|
||||
@@ -6,7 +6,6 @@ using BenchmarkDotNet.Attributes;
|
||||
using Content.IntegrationTests;
|
||||
using Content.IntegrationTests.Pair;
|
||||
using Content.Server.Mind;
|
||||
using Content.Server.Warps;
|
||||
using Content.Shared.Warps;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Analyzers;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using Content.Shared.Administration.Components;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Client.Administration.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class HeadstandComponent : SharedHeadstandComponent
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Client.Administration.Components;
|
||||
using Content.Shared.Administration.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Administration.Systems;
|
||||
|
||||
@@ -76,7 +76,7 @@ public sealed partial class ObjectsTab : Control
|
||||
switch (selection)
|
||||
{
|
||||
case ObjectsTabSelection.Stations:
|
||||
entities.AddRange(_entityManager.EntitySysManager.GetEntitySystem<StationSystem>().Stations);
|
||||
entities.AddRange(_entityManager.EntitySysManager.GetEntitySystem<StationSystem>().GetStationNames());
|
||||
break;
|
||||
case ObjectsTabSelection.Grids:
|
||||
{
|
||||
|
||||
5
Content.Client/Animals/Systems/ParrotMemorySystem.cs
Normal file
5
Content.Client/Animals/Systems/ParrotMemorySystem.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
using Content.Shared.Animals.Systems;
|
||||
|
||||
namespace Content.Client.Animals.Systems;
|
||||
|
||||
public sealed class ParrotMemorySystem : SharedParrotMemorySystem;
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Shared.Anomaly.Components;
|
||||
using Content.Shared.Anomaly.Effects;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Humanoid;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Anomaly.Effects;
|
||||
@@ -25,9 +25,8 @@ public sealed class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem
|
||||
|
||||
var index = _sprite.LayerMapReserve((ent.Owner, sprite), ent.Comp.LayerMap);
|
||||
|
||||
if (TryComp<BodyComponent>(ent, out var body) &&
|
||||
body.Prototype is not null &&
|
||||
ent.Comp.SpeciesSprites.TryGetValue(body.Prototype.Value, out var speciesSprite))
|
||||
if (TryComp<HumanoidAppearanceComponent>(ent, out var humanoidAppearance) &&
|
||||
ent.Comp.SpeciesSprites.TryGetValue(humanoidAppearance.Species, out var speciesSprite))
|
||||
{
|
||||
_sprite.LayerSetSprite((ent.Owner, sprite), index, speciesSprite);
|
||||
}
|
||||
|
||||
@@ -1,46 +1,11 @@
|
||||
using Content.Client.Atmos.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Content.Client.UserInterface.Systems.Storage.Controls;
|
||||
using Content.Shared.Atmos.Piping;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Atmos.Components;
|
||||
using Content.Shared.Item;
|
||||
|
||||
namespace Content.Client.Atmos.EntitySystems;
|
||||
|
||||
public sealed class PipeColorVisualizerSystem : VisualizerSystem<PipeColorVisualsComponent>
|
||||
{
|
||||
[Dependency] private readonly SharedItemSystem _itemSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<PipeColorVisualsComponent, GetInhandVisualsEvent>(OnGetVisuals);
|
||||
SubscribeLocalEvent<PipeColorVisualsComponent, BeforeRenderInGridEvent>(OnDrawInGrid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is used to display the color changes of the pipe on the screen..
|
||||
/// </summary>
|
||||
private void OnGetVisuals(Entity<PipeColorVisualsComponent> item, ref GetInhandVisualsEvent args)
|
||||
{
|
||||
foreach (var (_, layerData) in args.Layers)
|
||||
{
|
||||
if (TryComp(item.Owner, out AtmosPipeColorComponent? pipeColor))
|
||||
layerData.Color = pipeColor.Color;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is used to change the pipe's color in a container grid.
|
||||
/// </summary>
|
||||
private void OnDrawInGrid(Entity<PipeColorVisualsComponent> item, ref BeforeRenderInGridEvent args)
|
||||
{
|
||||
if (TryComp(item.Owner, out AtmosPipeColorComponent? pipeColor))
|
||||
args.Color = pipeColor.Color;
|
||||
}
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, PipeColorVisualsComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite)
|
||||
@@ -50,8 +15,6 @@ public sealed class PipeColorVisualizerSystem : VisualizerSystem<PipeColorVisual
|
||||
var layer = sprite[PipeVisualLayers.Pipe];
|
||||
layer.Color = color.WithAlpha(layer.Color.A);
|
||||
}
|
||||
|
||||
_itemSystem.VisualsChanged(uid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ public sealed partial class PumpControl : BoxContainer
|
||||
|
||||
foreach (var value in Enum.GetValues<VentPumpDirection>())
|
||||
{
|
||||
_pumpDirection.AddItem(Loc.GetString($"{value}"), (int) value);
|
||||
_pumpDirection.AddItem(Loc.GetString($"air-alarm-ui-pump-direction-{value.ToString().ToLower()}"), (int) value);
|
||||
}
|
||||
|
||||
_pumpDirection.SelectId((int) _data.PumpDirection);
|
||||
@@ -72,7 +72,7 @@ public sealed partial class PumpControl : BoxContainer
|
||||
|
||||
foreach (var value in Enum.GetValues<VentPressureBound>())
|
||||
{
|
||||
_pressureCheck.AddItem(Loc.GetString($"{value}"), (int) value);
|
||||
_pressureCheck.AddItem(Loc.GetString($"air-alarm-ui-pressure-bound-{value.ToString().ToLower()}"), (int) value);
|
||||
}
|
||||
|
||||
_pressureCheck.SelectId((int) _data.PressureChecks);
|
||||
|
||||
@@ -27,9 +27,15 @@
|
||||
</BoxContainer>
|
||||
<!-- Lower row: every single gas -->
|
||||
<Collapsible Margin="2 2 2 2">
|
||||
<CollapsibleHeading Title="Gas filters" />
|
||||
<CollapsibleHeading Title="{Loc 'air-alarm-ui-widget-gas-filters'}" />
|
||||
<CollapsibleBody Margin="20 0 0 0">
|
||||
<GridContainer HorizontalExpand="True" Name="CGasContainer" Columns="3" />
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<BoxContainer Margin="2">
|
||||
<Button Name="CSelectAll" Text="{Loc 'air-alarm-ui-scrubber-select-all-gases-label'}" />
|
||||
<Button Name="CDeselectAll" Text="{Loc 'air-alarm-ui-scrubber-deselect-all-gases-label'}" />
|
||||
</BoxContainer>
|
||||
<GridContainer Name="CGasContainer" Columns="3" />
|
||||
</BoxContainer>
|
||||
</CollapsibleBody>
|
||||
</Collapsible>
|
||||
</BoxContainer>
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.EntitySystems;
|
||||
using Content.Shared.Atmos.Monitor.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Atmos.Prototypes;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Atmos.Monitor.UI.Widgets;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class ScrubberControl : BoxContainer
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
|
||||
private GasVentScrubberData _data;
|
||||
private string _address;
|
||||
|
||||
@@ -22,12 +28,18 @@ public sealed partial class ScrubberControl : BoxContainer
|
||||
private FloatSpinBox _volumeRate => CVolumeRate;
|
||||
private CheckBox _wideNet => CWideNet;
|
||||
private Button _copySettings => CCopySettings;
|
||||
private Button _selectAll => CSelectAll;
|
||||
private Button _deselectAll => CDeselectAll;
|
||||
|
||||
private GridContainer _gases => CGasContainer;
|
||||
private Dictionary<Gas, Button> _gasControls = new();
|
||||
|
||||
public ScrubberControl(GasVentScrubberData data, string address)
|
||||
{
|
||||
|
||||
IoCManager.InjectDependencies(this);
|
||||
var atmosphereSystem = _entMan.System<SharedAtmosphereSystem>();
|
||||
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
Name = address;
|
||||
@@ -61,7 +73,7 @@ public sealed partial class ScrubberControl : BoxContainer
|
||||
|
||||
foreach (var value in Enum.GetValues<ScrubberPumpDirection>())
|
||||
{
|
||||
_pumpDirection.AddItem(Loc.GetString($"{value}"), (int) value);
|
||||
_pumpDirection.AddItem(Loc.GetString($"air-alarm-ui-pump-direction-{value.ToString().ToLower()}"), (int) value);
|
||||
}
|
||||
|
||||
_pumpDirection.SelectId((int) _data.PumpDirection);
|
||||
@@ -78,12 +90,28 @@ public sealed partial class ScrubberControl : BoxContainer
|
||||
ScrubberDataCopied?.Invoke(_data);
|
||||
};
|
||||
|
||||
foreach (var value in Enum.GetValues<Gas>())
|
||||
var allGases = Enum.GetValues<Gas>();
|
||||
_selectAll.OnPressed += _ =>
|
||||
{
|
||||
_data.FilterGases = new HashSet<Gas>(allGases);
|
||||
ScrubberDataChanged?.Invoke(_address, _data);
|
||||
};
|
||||
|
||||
_deselectAll.OnPressed += _ =>
|
||||
{
|
||||
_data.FilterGases = [];
|
||||
ScrubberDataChanged?.Invoke(_address, _data);
|
||||
};
|
||||
|
||||
foreach (var value in allGases)
|
||||
{
|
||||
ProtoId<GasPrototype> gasProtoId = atmosphereSystem.GetGas(value);
|
||||
var gasName = _prototypeManager.Index(gasProtoId).Name;
|
||||
|
||||
var gasButton = new Button
|
||||
{
|
||||
Name = value.ToString(),
|
||||
Text = Loc.GetString($"{value}"),
|
||||
Text = Loc.GetString(gasName),
|
||||
ToggleMode = true,
|
||||
HorizontalExpand = true,
|
||||
Pressed = _data.FilterGases.Contains(value)
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
using Content.Client.Message;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.EntitySystems;
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.Atmos.Prototypes;
|
||||
using Content.Shared.Temperature;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Atmos.Monitor.UI.Widgets;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class SensorInfo : BoxContainer
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
|
||||
public Action<string, AtmosMonitorThresholdType, AtmosAlarmThreshold, Gas?>? OnThresholdUpdate;
|
||||
public event Action<AtmosSensorData>? SensorDataCopied;
|
||||
private string _address;
|
||||
@@ -23,6 +29,9 @@ public sealed partial class SensorInfo : BoxContainer
|
||||
|
||||
public SensorInfo(AtmosSensorData data, string address)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
var atmosphereSystem = _entMan.System<SharedAtmosphereSystem>();
|
||||
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
_address = address;
|
||||
@@ -45,8 +54,12 @@ public sealed partial class SensorInfo : BoxContainer
|
||||
var label = new RichTextLabel();
|
||||
|
||||
var fractionGas = amount / data.TotalMoles;
|
||||
|
||||
ProtoId<GasPrototype> gasProtoId = atmosphereSystem.GetGas(gas);
|
||||
var gasName = _prototypeManager.Index(gasProtoId).Name;
|
||||
|
||||
label.SetMarkup(Loc.GetString("air-alarm-ui-gases-indicator",
|
||||
("gas", $"{gas}"),
|
||||
("gas", Loc.GetString(gasName)),
|
||||
("color", AirAlarmWindow.ColorForThreshold(fractionGas, data.GasThresholds[gas])),
|
||||
("amount", $"{amount:0.####}"),
|
||||
("percentage", $"{(100 * fractionGas):0.##}")));
|
||||
@@ -54,7 +67,7 @@ public sealed partial class SensorInfo : BoxContainer
|
||||
_gasLabels.Add(gas, label);
|
||||
|
||||
var threshold = data.GasThresholds[gas];
|
||||
var gasThresholdControl = new ThresholdControl(Loc.GetString($"air-alarm-ui-thresholds-gas-title", ("gas", $"{gas}")), threshold, AtmosMonitorThresholdType.Gas, gas, 100);
|
||||
var gasThresholdControl = new ThresholdControl(Loc.GetString($"air-alarm-ui-thresholds-gas-title"), threshold, AtmosMonitorThresholdType.Gas, gas, 100);
|
||||
gasThresholdControl.Margin = new Thickness(20, 2, 2, 2);
|
||||
gasThresholdControl.ThresholdDataChanged += (type, alarmThreshold, arg3) =>
|
||||
{
|
||||
@@ -90,6 +103,9 @@ public sealed partial class SensorInfo : BoxContainer
|
||||
|
||||
public void ChangeData(AtmosSensorData data)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
var atmosphereSystem = _entMan.System<SharedAtmosphereSystem>();
|
||||
|
||||
SensorAddress.Title = Loc.GetString("air-alarm-ui-window-listing-title", ("address", _address), ("state", data.AlarmState));
|
||||
|
||||
AlarmStateLabel.SetMarkup(Loc.GetString("air-alarm-ui-window-alarm-state-indicator",
|
||||
@@ -112,8 +128,12 @@ public sealed partial class SensorInfo : BoxContainer
|
||||
}
|
||||
|
||||
var fractionGas = amount / data.TotalMoles;
|
||||
|
||||
ProtoId<GasPrototype> gasProtoId = atmosphereSystem.GetGas(gas);
|
||||
var gasName = _prototypeManager.Index(gasProtoId).Name;
|
||||
|
||||
label.SetMarkup(Loc.GetString("air-alarm-ui-gases-indicator",
|
||||
("gas", $"{gas}"),
|
||||
("gas", Loc.GetString(gasName)),
|
||||
("color", AirAlarmWindow.ColorForThreshold(fractionGas, data.GasThresholds[gas])),
|
||||
("amount", $"{amount:0.####}"),
|
||||
("percentage", $"{(100 * fractionGas):0.##}")));
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
HorizontalExpand="True" Orientation="Vertical"
|
||||
Margin = "20 0 0 0" MinSize="160 0" >
|
||||
<Label Name="CBoundLabel" HorizontalAlignment="Center" />
|
||||
<CheckBox Name="CBoundEnabled" HorizontalAlignment="Center" Text="{Loc 'Enable'}" Pressed="True" />
|
||||
<CheckBox Name="CBoundEnabled" HorizontalAlignment="Center" Text="{Loc 'air-alarm-ui-widget-enable'}" Pressed="True" />
|
||||
<FloatSpinBox Name="CSpinner" />
|
||||
</BoxContainer>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<CollapsibleBody Margin="20 0 0 0">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<CheckBox Name="CEnabled" Text="{Loc 'Enabled'}" />
|
||||
<CheckBox Name="CEnabled" Text="{Loc 'air-alarm-ui-widget-enable'}" />
|
||||
</BoxContainer>
|
||||
<!-- Upper row: Danger bounds -->
|
||||
<BoxContainer Name="CDangerBounds" Orientation="Horizontal" Margin="0 0 0 2"/>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.CardboardBox;
|
||||
using Content.Shared.CardboardBox.Components;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
@@ -15,13 +15,13 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
|
||||
[Dependency] private readonly ExamineSystemShared _examine = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
private EntityQuery<BodyComponent> _bodyQuery;
|
||||
private EntityQuery<MobStateComponent> _mobStateQuery;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_bodyQuery = GetEntityQuery<BodyComponent>();
|
||||
_mobStateQuery = GetEntityQuery<MobStateComponent>();
|
||||
|
||||
SubscribeNetworkEvent<PlayBoxEffectMessage>(OnBoxEffect);
|
||||
}
|
||||
@@ -66,8 +66,8 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
|
||||
if (!_examine.InRangeUnOccluded(sourcePos, mapPos, box.Distance, null))
|
||||
continue;
|
||||
|
||||
// no effect for anything too exotic
|
||||
if (!_bodyQuery.HasComp(mob))
|
||||
// no effect for non-mobs that have MobMover, such as mechs and vehicles.
|
||||
if (!_mobStateQuery.HasComp(mob))
|
||||
continue;
|
||||
|
||||
var ent = Spawn(box.Effect, mapPos);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using Content.Shared.Changeling.Transform;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client.Changeling.Transform;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed partial class ChangelingTransformBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
|
||||
{
|
||||
private ChangelingTransformMenu? _window;
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<ChangelingTransformMenu>();
|
||||
|
||||
_window.OnIdentitySelect += SendIdentitySelect;
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (state is not ChangelingTransformBoundUserInterfaceState current)
|
||||
return;
|
||||
|
||||
_window?.UpdateState(current);
|
||||
}
|
||||
|
||||
public void SendIdentitySelect(NetEntity identityId)
|
||||
{
|
||||
SendPredictedMessage(new ChangelingTransformIdentitySelectMessage(identityId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<ui:RadialMenu
|
||||
xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
CloseButtonStyleClass="RadialMenuCloseButton"
|
||||
VerticalExpand="True"
|
||||
HorizontalExpand="True">
|
||||
<ui:RadialContainer Name="Main">
|
||||
</ui:RadialContainer>
|
||||
</ui:RadialMenu>
|
||||
@@ -0,0 +1,60 @@
|
||||
using System.Numerics;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Changeling.Transform;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.Changeling.Transform;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class ChangelingTransformMenu : RadialMenu
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entity = default!;
|
||||
public event Action<NetEntity>? OnIdentitySelect;
|
||||
|
||||
public ChangelingTransformMenu()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
public void UpdateState(ChangelingTransformBoundUserInterfaceState state)
|
||||
{
|
||||
Main.DisposeAllChildren();
|
||||
foreach (var identity in state.Identites)
|
||||
{
|
||||
var identityUid = _entity.GetEntity(identity);
|
||||
|
||||
if (!_entity.TryGetComponent<MetaDataComponent>(identityUid, out var metadata))
|
||||
continue;
|
||||
|
||||
var identityName = metadata.EntityName;
|
||||
|
||||
var button = new ChangelingTransformMenuButton()
|
||||
{
|
||||
StyleClasses = { "RadialMenuButton" },
|
||||
SetSize = new Vector2(64, 64),
|
||||
ToolTip = identityName,
|
||||
};
|
||||
|
||||
var entView = new SpriteView()
|
||||
{
|
||||
SetSize = new Vector2(48, 48),
|
||||
VerticalAlignment = VAlignment.Center,
|
||||
HorizontalAlignment = HAlignment.Center,
|
||||
Stretch = SpriteView.StretchMode.Fill,
|
||||
};
|
||||
entView.SetEntity(identityUid);
|
||||
button.OnButtonUp += _ =>
|
||||
{
|
||||
OnIdentitySelect?.Invoke(identity);
|
||||
Close();
|
||||
};
|
||||
button.AddChild(entView);
|
||||
Main.AddChild(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ChangelingTransformMenuButton : RadialMenuTextureButtonWithSector;
|
||||
5
Content.Client/Cloning/CloningSystem.cs
Normal file
5
Content.Client/Cloning/CloningSystem.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
using Content.Shared.Cloning;
|
||||
|
||||
namespace Content.Client.Cloning;
|
||||
|
||||
public sealed partial class CloningSystem : SharedCloningSystem;
|
||||
@@ -356,6 +356,7 @@ public sealed partial class CreditsWindow : DefaultWindow
|
||||
AddSection(Loc.GetString("credits-window-contributors-section-title"), "GitHub.txt");
|
||||
AddSection(Loc.GetString("credits-window-codebases-section-title"), "SpaceStation13.txt");
|
||||
AddSection(Loc.GetString("credits-window-original-remake-team-section-title"), "OriginalRemake.txt");
|
||||
AddSection(Loc.GetString("credits-window-immortals-title"), "Immortals.txt", true);
|
||||
AddSection(Loc.GetString("credits-window-special-thanks-section-title"), "SpecialThanks.txt", true);
|
||||
|
||||
var linkGithub = _cfg.GetCVar(CCVars.InfoLinksGithub);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
using Content.Shared.Explosion.EntitySystems;
|
||||
|
||||
namespace Content.Client.Explosion;
|
||||
|
||||
public sealed class SmokeOnTriggerSystem : SharedSmokeOnTriggerSystem
|
||||
{
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
using Content.Shared.Explosion;
|
||||
using Content.Shared.Explosion.Components;
|
||||
|
||||
namespace Content.Client.Explosion;
|
||||
|
||||
[RegisterComponent, Access(typeof(TriggerSystem))]
|
||||
public sealed partial class TriggerOnProximityComponent : SharedTriggerOnProximityComponent {}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Content.Client.Explosion;
|
||||
|
||||
public sealed partial class TriggerSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
InitializeProximity();
|
||||
}
|
||||
}
|
||||
5
Content.Client/Forensics/Systems/ForensicsSystem.cs
Normal file
5
Content.Client/Forensics/Systems/ForensicsSystem.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
using Content.Shared.Forensics.Systems;
|
||||
|
||||
namespace Content.Client.Forensics.Systems;
|
||||
|
||||
public sealed class ForensicsSystem : SharedForensicsSystem;
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared.HotPotato;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.HotPotato;
|
||||
@@ -10,6 +11,9 @@ public sealed class HotPotatoSystem : SharedHotPotatoSystem
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
private readonly EntProtoId _hotPotatoEffectId = "HotPotatoEffect";
|
||||
|
||||
// TODO: particle system
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
@@ -23,7 +27,7 @@ public sealed class HotPotatoSystem : SharedHotPotatoSystem
|
||||
if (_timing.CurTime < comp.TargetTime)
|
||||
continue;
|
||||
comp.TargetTime = _timing.CurTime + TimeSpan.FromSeconds(comp.EffectCooldown);
|
||||
Spawn("HotPotatoEffect", _transform.GetMapCoordinates(uid).Offset(_random.NextVector2(0.25f)));
|
||||
Spawn(_hotPotatoEffectId, _transform.GetMapCoordinates(uid).Offset(_random.NextVector2(0.25f)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +294,6 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
|
||||
SetMaster(uid, null);
|
||||
TrySetChannels(uid, data);
|
||||
|
||||
instrument.MidiEventBuffer.Clear();
|
||||
instrument.Renderer.OnMidiEvent += instrument.MidiEventBuffer.Add;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -115,6 +115,13 @@ namespace Content.Client.Inventory
|
||||
OnLinkInventorySlots?.Invoke(uid, component);
|
||||
}
|
||||
|
||||
protected override void OnInit(Entity<InventoryComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
base.OnInit(ent, ref args);
|
||||
|
||||
_clothingVisualsSystem.InitClothing(ent.Owner, ent.Comp);
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
CommandBinds.Unregister<ClientInventorySystem>();
|
||||
@@ -261,7 +268,6 @@ namespace Content.Client.Inventory
|
||||
TryAddSlotData((ent.Owner, inventorySlots), (SlotData)slot);
|
||||
}
|
||||
|
||||
_clothingVisualsSystem.InitClothing(ent, ent.Comp);
|
||||
if (ent.Owner == _playerManager.LocalEntity)
|
||||
ReloadInventory(inventorySlots);
|
||||
}
|
||||
|
||||
@@ -1,36 +1,46 @@
|
||||
using Content.Shared.Light.Components;
|
||||
using Content.Shared.Light.EntitySystems;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Light.Visualizers;
|
||||
namespace Content.Client.Light.EntitySystems;
|
||||
|
||||
public sealed class LightBulbSystem : VisualizerSystem<LightBulbComponent>
|
||||
public sealed class LightBulbSystem : SharedLightBulbSystem
|
||||
{
|
||||
protected override void OnAppearanceChange(EntityUid uid, LightBulbComponent comp, ref AppearanceChangeEvent args)
|
||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<LightBulbComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(EntityUid uid, LightBulbComponent comp, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
// update sprite state
|
||||
if (AppearanceSystem.TryGetData<LightBulbState>(uid, LightBulbVisuals.State, out var state, args.Component))
|
||||
if (_appearance.TryGetData<LightBulbState>(uid, LightBulbVisuals.State, out var state, args.Component))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case LightBulbState.Normal:
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), LightBulbVisualLayers.Base, comp.NormalSpriteState);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), LightBulbVisualLayers.Base, comp.NormalSpriteState);
|
||||
break;
|
||||
case LightBulbState.Broken:
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), LightBulbVisualLayers.Base, comp.BrokenSpriteState);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), LightBulbVisualLayers.Base, comp.BrokenSpriteState);
|
||||
break;
|
||||
case LightBulbState.Burned:
|
||||
SpriteSystem.LayerSetRsiState((uid, args.Sprite), LightBulbVisualLayers.Base, comp.BurnedSpriteState);
|
||||
_sprite.LayerSetRsiState((uid, args.Sprite), LightBulbVisualLayers.Base, comp.BurnedSpriteState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// also update sprites color
|
||||
if (AppearanceSystem.TryGetData<Color>(uid, LightBulbVisuals.Color, out var color, args.Component))
|
||||
if (_appearance.TryGetData<Color>(uid, LightBulbVisuals.Color, out var color, args.Component))
|
||||
{
|
||||
SpriteSystem.SetColor((uid, args.Sprite), color);
|
||||
_sprite.SetColor((uid, args.Sprite), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
5
Content.Client/Light/EntitySystems/PoweredLightSystem.cs
Normal file
5
Content.Client/Light/EntitySystems/PoweredLightSystem.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
using Content.Shared.Light.EntitySystems;
|
||||
|
||||
namespace Content.Client.Light.EntitySystems;
|
||||
|
||||
public sealed class PoweredLightSystem : SharedPoweredLightSystem;
|
||||
@@ -1021,7 +1021,7 @@ namespace Content.Client.Lobby.UI
|
||||
|
||||
_loadoutWindow = new LoadoutWindow(Profile, roleLoadout, roleLoadoutProto, _playerManager.LocalSession, collection)
|
||||
{
|
||||
Title = jobProto?.ID + "-loadout",
|
||||
Title = Loc.GetString("loadout-window-title-loadout", ("job", $"{jobProto?.LocalizedName}")),
|
||||
};
|
||||
|
||||
// Refresh the buttons etc.
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Emag.Systems;
|
||||
using Content.Shared.Medical.Cryogenics;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Medical.Cryogenics;
|
||||
@@ -15,11 +13,6 @@ public sealed class CryoPodSystem : SharedCryoPodSystem
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CryoPodComponent, ComponentInit>(OnComponentInit);
|
||||
SubscribeLocalEvent<CryoPodComponent, GetVerbsEvent<AlternativeVerb>>(AddAlternativeVerbs);
|
||||
SubscribeLocalEvent<CryoPodComponent, GotEmaggedEvent>(OnEmagged);
|
||||
SubscribeLocalEvent<CryoPodComponent, CryoPodPryFinished>(OnCryoPodPryFinished);
|
||||
|
||||
SubscribeLocalEvent<CryoPodComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
SubscribeLocalEvent<InsideCryoPodComponent, ComponentStartup>(OnCryoPodInsertion);
|
||||
SubscribeLocalEvent<InsideCryoPodComponent, ComponentRemove>(OnCryoPodRemoval);
|
||||
@@ -53,8 +46,8 @@ public sealed class CryoPodSystem : SharedCryoPodSystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_appearance.TryGetData<bool>(uid, CryoPodComponent.CryoPodVisuals.ContainsEntity, out var isOpen, args.Component)
|
||||
|| !_appearance.TryGetData<bool>(uid, CryoPodComponent.CryoPodVisuals.IsOn, out var isOn, args.Component))
|
||||
if (!_appearance.TryGetData<bool>(uid, CryoPodVisuals.ContainsEntity, out var isOpen, args.Component)
|
||||
|| !_appearance.TryGetData<bool>(uid, CryoPodVisuals.IsOn, out var isOn, args.Component))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
5
Content.Client/Medical/SuitSensors/SuitSensorSystem.cs
Normal file
5
Content.Client/Medical/SuitSensors/SuitSensorSystem.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
using Content.Shared.Medical.SuitSensors;
|
||||
|
||||
namespace Content.Client.Medical.SuitSensors;
|
||||
|
||||
public sealed class SuitSensorSystem : SharedSuitSensorSystem;
|
||||
@@ -5,15 +5,15 @@
|
||||
<BoxContainer Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True">
|
||||
<networkConfigurator:NetworkConfiguratorDeviceList Name="DeviceList" MinHeight="500" />
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="8 8 8 1">
|
||||
<Button Name="Set" Text="Set" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-set'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
|
||||
<Button Name="Add" Text="Add" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-add'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
|
||||
<Button Name="Set" Text="{Loc 'network-configurator-text-set'}" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-set'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
|
||||
<Button Name="Add" Text="{Loc 'network-configurator-text-add'}" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-add'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
|
||||
<!-- Edit might not be needed -->
|
||||
<!--<Button Name="Edit" Text="Edit" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-edit'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>-->
|
||||
<Button Name="Clear" Text="Clear" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-clear'}" HorizontalExpand="True"/>
|
||||
<Button Name="Clear" Text="{Loc 'network-configurator-text-clear'}" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-clear'}" HorizontalExpand="True"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="8 0 8 8">
|
||||
<Button Name="Copy" Text="Copy" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-copy'}" HorizontalExpand="True" StyleClasses="OpenRight"/>
|
||||
<Button Name="Show" Text="Show" Access="Public" ToggleMode="True" ToolTip="{Loc 'network-configurator-tooltip-show'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
|
||||
<Button Name="Copy" Text="{Loc 'network-configurator-text-copy'}" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-copy'}" HorizontalExpand="True" StyleClasses="OpenRight"/>
|
||||
<Button Name="Show" Text="{Loc 'network-configurator-text-show'}" Access="Public" ToggleMode="True" ToolTip="{Loc 'network-configurator-tooltip-show'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
|
||||
</BoxContainer>
|
||||
<Label Name="Count" StyleClasses="LabelSubText" HorizontalAlignment="Right" Margin="0 0 12 8"/>
|
||||
</BoxContainer>
|
||||
|
||||
@@ -94,7 +94,7 @@ public sealed class ClientsidePlaytimeTrackingManager
|
||||
return;
|
||||
}
|
||||
|
||||
// At less than 1 minute of time diff, there's not much point, and saving regardless will brick tests
|
||||
// At less than 1 minute of time diff, there's not much point
|
||||
// The reason this isn't checking for 0 is because TotalMinutes is fractional, rather than solely whole minutes
|
||||
if (timeDiffMinutes < 1)
|
||||
return;
|
||||
|
||||
@@ -5,4 +5,5 @@ namespace Content.Client.Power.Components;
|
||||
[RegisterComponent]
|
||||
public sealed partial class ApcPowerReceiverComponent : SharedApcPowerReceiverComponent
|
||||
{
|
||||
public override float Load { get; set; }
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow
|
||||
|
||||
public EntityUid Entity;
|
||||
|
||||
private bool _allowBorgControl = true;
|
||||
|
||||
public RoboticsConsoleWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
@@ -72,6 +74,7 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow
|
||||
public void UpdateState(RoboticsConsoleState state)
|
||||
{
|
||||
_cyborgs = state.Cyborgs;
|
||||
_allowBorgControl = state.AllowBorgControl;
|
||||
|
||||
// clear invalid selection
|
||||
if (_selected is {} selected && !_cyborgs.ContainsKey(selected))
|
||||
@@ -85,8 +88,8 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow
|
||||
PopulateData();
|
||||
|
||||
var locked = _lock.IsLocked(Entity);
|
||||
DangerZone.Visible = !locked;
|
||||
LockedMessage.Visible = locked;
|
||||
DangerZone.Visible = !locked && _allowBorgControl;
|
||||
LockedMessage.Visible = locked && _allowBorgControl; // Only show if locked AND control is allowed
|
||||
}
|
||||
|
||||
private void PopulateCyborgs()
|
||||
@@ -120,11 +123,19 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow
|
||||
BorgSprite.Texture = _sprite.Frame0(data.ChassisSprite!);
|
||||
|
||||
var batteryColor = data.Charge switch {
|
||||
< 0.2f => "red",
|
||||
< 0.4f => "orange",
|
||||
< 0.6f => "yellow",
|
||||
< 0.8f => "green",
|
||||
_ => "blue"
|
||||
< 0.2f => "#FF6C7F", // red
|
||||
< 0.4f => "#EF973C", // orange
|
||||
< 0.6f => "#E8CB2D", // yellow
|
||||
< 0.8f => "#30CC19", // green
|
||||
_ => "#00D3B8" // cyan
|
||||
};
|
||||
|
||||
var hpPercentColor = data.HpPercent switch {
|
||||
< 0.2f => "#FF6C7F", // red
|
||||
< 0.4f => "#EF973C", // orange
|
||||
< 0.6f => "#E8CB2D", // yellow
|
||||
< 0.8f => "#30CC19", // green
|
||||
_ => "#00D3B8" // cyan
|
||||
};
|
||||
|
||||
var text = new FormattedMessage();
|
||||
@@ -132,12 +143,14 @@ public sealed partial class RoboticsConsoleWindow : FancyWindow
|
||||
text.AddMarkupOrThrow(Loc.GetString("robotics-console-designation"));
|
||||
text.AddText($" {data.Name}\n"); // prevent players trolling by naming borg [color=red]satan[/color]
|
||||
text.AddMarkupOrThrow($"{Loc.GetString("robotics-console-battery", ("charge", (int)(data.Charge * 100f)), ("color", batteryColor))}\n");
|
||||
text.AddMarkupOrThrow($"{Loc.GetString("robotics-console-hp", ("hp", (int)(data.HpPercent * 100f)), ("color", hpPercentColor))}\n");
|
||||
text.AddMarkupOrThrow($"{Loc.GetString("robotics-console-brain", ("brain", data.HasBrain))}\n");
|
||||
text.AddMarkupOrThrow(Loc.GetString("robotics-console-modules", ("count", data.ModuleCount)));
|
||||
BorgInfo.SetMessage(text);
|
||||
|
||||
// how the turntables
|
||||
DisableButton.Disabled = !(data.HasBrain && data.CanDisable);
|
||||
DisableButton.Disabled = !_allowBorgControl || !(data.HasBrain && data.CanDisable);
|
||||
DestroyButton.Disabled = !_allowBorgControl;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
|
||||
@@ -24,7 +24,7 @@ public sealed class RotationVisualizerSystem : SharedRotationVisualsSystem
|
||||
return;
|
||||
|
||||
if (!_appearance.TryGetData<RotationState>(uid, RotationVisuals.RotationState, out var state, args.Component))
|
||||
return;
|
||||
state = RotationState.Vertical;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
|
||||
@@ -40,6 +40,8 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
|
||||
private readonly HashSet<DockingPortState> _drawnDocks = new();
|
||||
private readonly Dictionary<DockingPortState, Button> _dockButtons = new();
|
||||
|
||||
private readonly Color _fallbackHighlightedColor = Color.Magenta;
|
||||
|
||||
/// <summary>
|
||||
/// Store buttons for every other dock
|
||||
/// </summary>
|
||||
@@ -213,11 +215,11 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
|
||||
|
||||
if (HighlightedDock == dock.Entity)
|
||||
{
|
||||
otherDockColor = Color.ToSrgb(Color.Magenta);
|
||||
otherDockColor = Color.ToSrgb(dock.HighlightedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
otherDockColor = Color.ToSrgb(Color.Purple);
|
||||
otherDockColor = Color.ToSrgb(dock.Color);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -311,7 +313,7 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
|
||||
ScalePosition(Vector2.Transform(new Vector2(-0.5f, 0.5f), rotation)),
|
||||
ScalePosition(Vector2.Transform(new Vector2(0.5f, -0.5f), rotation)));
|
||||
|
||||
var dockColor = Color.Magenta;
|
||||
var dockColor = _viewedState?.HighlightedColor ?? _fallbackHighlightedColor;
|
||||
var connectionColor = Color.Pink;
|
||||
|
||||
handle.DrawRect(ourDockConnection, connectionColor.WithAlpha(0.2f));
|
||||
|
||||
@@ -308,7 +308,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
|
||||
-dockRadius * UIScale,
|
||||
(Size.X + dockRadius) * UIScale,
|
||||
(Size.Y + dockRadius) * UIScale);
|
||||
|
||||
|
||||
if (_docks.TryGetValue(nent, out var docks))
|
||||
{
|
||||
foreach (var state in docks)
|
||||
@@ -321,7 +321,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
|
||||
continue;
|
||||
}
|
||||
|
||||
var color = Color.ToSrgb(Color.Magenta);
|
||||
var color = Color.ToSrgb(state.HighlightedColor);
|
||||
|
||||
var verts = new[]
|
||||
{
|
||||
|
||||
@@ -12,6 +12,8 @@ public sealed class EmitterSystem : SharedEmitterSystem
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<EmitterComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
}
|
||||
|
||||
|
||||
38
Content.Client/Sprite/ScaleVisualsSystem.cs
Normal file
38
Content.Client/Sprite/ScaleVisualsSystem.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Sprite;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Sprite;
|
||||
|
||||
public sealed class ScaleVisualsSystem : SharedScaleVisualsSystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ScaleVisualsComponent, AppearanceChangeEvent>(OnChangeData);
|
||||
}
|
||||
|
||||
private void OnChangeData(Entity<ScaleVisualsComponent> ent, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (!args.AppearanceData.TryGetValue(ScaleVisuals.Scale, out var scale) ||
|
||||
args.Sprite == null) return;
|
||||
|
||||
// save the original scale
|
||||
ent.Comp.OriginalScale ??= args.Sprite.Scale;
|
||||
|
||||
var vecScale = (Vector2)scale;
|
||||
_sprite.SetScale((ent.Owner, args.Sprite), vecScale);
|
||||
}
|
||||
|
||||
// revert to the original scale
|
||||
protected override void ResetScale(Entity<ScaleVisualsComponent> ent)
|
||||
{
|
||||
base.ResetScale(ent);
|
||||
|
||||
if (ent.Comp.OriginalScale != null)
|
||||
_sprite.SetScale(ent.Owner, ent.Comp.OriginalScale.Value);
|
||||
}
|
||||
}
|
||||
@@ -28,22 +28,8 @@ namespace Content.Client.Stack
|
||||
|
||||
base.SetCount(uid, amount, component);
|
||||
|
||||
if (component.Lingering &&
|
||||
TryComp<SpriteComponent>(uid, out var sprite))
|
||||
{
|
||||
// tint the stack gray and make it transparent if it's lingering.
|
||||
var color = component.Count == 0 && component.Lingering
|
||||
? Color.DarkGray.WithAlpha(0.65f)
|
||||
: Color.White;
|
||||
|
||||
for (var i = 0; i < sprite.AllLayers.Count(); i++)
|
||||
{
|
||||
_sprite.LayerSetColor((uid, sprite), i, color);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO PREDICT ENTITY DELETION: This should really just be a normal entity deletion call.
|
||||
if (component.Count <= 0 && !component.Lingering)
|
||||
if (component.Count <= 0)
|
||||
{
|
||||
Xform.DetachEntity(uid, Transform(uid));
|
||||
return;
|
||||
|
||||
@@ -2,34 +2,5 @@
|
||||
|
||||
namespace Content.Client.Station;
|
||||
|
||||
/// <summary>
|
||||
/// This handles letting the client know stations are a thing. Only really used by an admin menu.
|
||||
/// </summary>
|
||||
public sealed partial class StationSystem : SharedStationSystem
|
||||
{
|
||||
private readonly List<(string Name, NetEntity Entity)> _stations = new();
|
||||
|
||||
/// <summary>
|
||||
/// All stations that currently exist.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// I'd have this just invoke an entity query, but we're on the client and the client barely knows about stations.
|
||||
/// </remarks>
|
||||
// TODO: Stations have a global PVS override now, this can probably be changed into a query.
|
||||
public IReadOnlyList<(string Name, NetEntity Entity)> Stations => _stations;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeNetworkEvent<StationsUpdatedEvent>(StationsUpdated);
|
||||
}
|
||||
|
||||
private void StationsUpdated(StationsUpdatedEvent ev)
|
||||
{
|
||||
_stations.Clear();
|
||||
// TODO this needs to be done in component states and with the Ensure() methods
|
||||
_stations.AddRange(ev.Stations);
|
||||
}
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public sealed partial class StationSystem : SharedStationSystem;
|
||||
|
||||
@@ -40,6 +40,11 @@ public sealed class StorageSystem : SharedStorageSystem
|
||||
component.MaxItemSize = state.MaxItemSize;
|
||||
component.Whitelist = state.Whitelist;
|
||||
component.Blacklist = state.Blacklist;
|
||||
component.StorageInsertSound = state.StorageInsertSound;
|
||||
component.StorageRemoveSound = state.StorageRemoveSound;
|
||||
component.StorageOpenSound = state.StorageOpenSound;
|
||||
component.StorageCloseSound = state.StorageCloseSound;
|
||||
component.DefaultStorageOrientation = state.DefaultStorageOrientation;
|
||||
|
||||
_oldStoredItems.Clear();
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
Name="RefundButton"
|
||||
MinWidth="64"
|
||||
HorizontalAlignment="Right"
|
||||
Text="Refund" />
|
||||
Text="{Loc 'store-ui-refund-text'}" />
|
||||
</BoxContainer>
|
||||
<LineEdit Name="SearchBar" Margin="4" PlaceHolder="Search" HorizontalExpand="True"/>
|
||||
<PanelContainer VerticalExpand="True">
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using Content.Client.Trigger.Systems;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Client.Trigger;
|
||||
namespace Content.Client.Trigger.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
[Access(typeof(TimerTriggerVisualizerSystem))]
|
||||
@@ -16,28 +17,27 @@ public sealed partial class TimerTriggerVisualsComponent : Component
|
||||
/// <summary>
|
||||
/// The RSI state used while the device has not been primed.
|
||||
/// </summary>
|
||||
[DataField("unprimedSprite")]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public string UnprimedSprite = "icon";
|
||||
|
||||
/// <summary>
|
||||
/// The RSI state used when the device is primed.
|
||||
/// Not VVWrite-able because it's only used at component init to construct the priming animation.
|
||||
/// </summary>
|
||||
[DataField("primingSprite")]
|
||||
[DataField]
|
||||
public string PrimingSprite = "primed";
|
||||
|
||||
/// <summary>
|
||||
/// The sound played when the device is primed.
|
||||
/// Not VVWrite-able because it's only used at component init to construct the priming animation.
|
||||
/// </summary>
|
||||
[DataField("primingSound")]
|
||||
[DataField, ViewVariables]
|
||||
public SoundSpecifier? PrimingSound;
|
||||
|
||||
/// <summary>
|
||||
/// The actual priming animation.
|
||||
/// Constructed at component init from the sprite and sound.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[ViewVariables]
|
||||
public Animation PrimingAnimation = default!;
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
using Content.Shared.Trigger;
|
||||
using Content.Shared.Trigger.Components.Triggers;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Animations;
|
||||
|
||||
namespace Content.Client.Explosion;
|
||||
namespace Content.Client.Trigger.Systems;
|
||||
|
||||
public sealed partial class TriggerSystem
|
||||
public sealed class ProximityTriggerAnimationSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _player = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
@@ -18,7 +19,7 @@ public sealed partial class TriggerSystem
|
||||
|
||||
private const string AnimKey = "proximity";
|
||||
|
||||
private static readonly Animation _flasherAnimation = new Animation
|
||||
private static readonly Animation FlasherAnimation = new Animation
|
||||
{
|
||||
Length = TimeSpan.FromSeconds(0.6f),
|
||||
AnimationTracks = {
|
||||
@@ -42,8 +43,10 @@ public sealed partial class TriggerSystem
|
||||
}
|
||||
};
|
||||
|
||||
private void InitializeProximity()
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<TriggerOnProximityComponent, ComponentInit>(OnProximityInit);
|
||||
SubscribeLocalEvent<TriggerOnProximityComponent, AppearanceChangeEvent>(OnProxAppChange);
|
||||
SubscribeLocalEvent<TriggerOnProximityComponent, AnimationCompletedEvent>(OnProxAnimation);
|
||||
@@ -94,7 +97,7 @@ public sealed partial class TriggerSystem
|
||||
break;
|
||||
case ProximityTriggerVisuals.Active:
|
||||
if (_player.HasRunningAnimation(uid, player, AnimKey)) return;
|
||||
_player.Play((uid, player), _flasherAnimation, AnimKey);
|
||||
_player.Play((uid, player), FlasherAnimation, AnimKey);
|
||||
break;
|
||||
case ProximityTriggerVisuals.Off:
|
||||
default:
|
||||
@@ -0,0 +1,5 @@
|
||||
using Content.Shared.Trigger.Systems;
|
||||
|
||||
namespace Content.Client.Trigger.Systems;
|
||||
|
||||
public sealed class ReleaseGasOnTriggerSystem : SharedReleaseGasOnTriggerSystem;
|
||||
@@ -1,11 +1,10 @@
|
||||
using Content.Client.Trigger.Components;
|
||||
using Content.Shared.Trigger;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client.Trigger;
|
||||
namespace Content.Client.Trigger.Systems;
|
||||
|
||||
public sealed class TimerTriggerVisualizerSystem : VisualizerSystem<TimerTriggerVisualsComponent>
|
||||
{
|
||||
@@ -17,25 +16,26 @@ public sealed class TimerTriggerVisualizerSystem : VisualizerSystem<TimerTrigger
|
||||
SubscribeLocalEvent<TimerTriggerVisualsComponent, ComponentInit>(OnComponentInit);
|
||||
}
|
||||
|
||||
private void OnComponentInit(EntityUid uid, TimerTriggerVisualsComponent comp, ComponentInit args)
|
||||
private void OnComponentInit(Entity<TimerTriggerVisualsComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
comp.PrimingAnimation = new Animation
|
||||
ent.Comp.PrimingAnimation = new Animation
|
||||
{
|
||||
Length = TimeSpan.MaxValue,
|
||||
AnimationTracks = {
|
||||
new AnimationTrackSpriteFlick() {
|
||||
new AnimationTrackSpriteFlick()
|
||||
{
|
||||
LayerKey = TriggerVisualLayers.Base,
|
||||
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.PrimingSprite, 0f) }
|
||||
KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(ent.Comp.PrimingSprite, 0f) }
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (comp.PrimingSound != null)
|
||||
if (ent.Comp.PrimingSound != null)
|
||||
{
|
||||
comp.PrimingAnimation.AnimationTracks.Add(
|
||||
ent.Comp.PrimingAnimation.AnimationTracks.Add(
|
||||
new AnimationTrackPlaySound()
|
||||
{
|
||||
KeyFrames = { new AnimationTrackPlaySound.KeyFrame(_audioSystem.ResolveSound(comp.PrimingSound), 0) }
|
||||
KeyFrames = { new AnimationTrackPlaySound.KeyFrame(_audioSystem.ResolveSound(ent.Comp.PrimingSound), 0) }
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using System.Numerics;
|
||||
using Content.Client.Cooldown;
|
||||
using Content.Client.UserInterface.Systems.Inventory.Controls;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.UserInterface.Controls
|
||||
{
|
||||
@@ -20,6 +22,7 @@ namespace Content.Client.UserInterface.Controls
|
||||
public CooldownGraphic CooldownDisplay { get; }
|
||||
|
||||
private SpriteView SpriteView { get; }
|
||||
private EntityPrototypeView ProtoView { get; }
|
||||
|
||||
public EntityUid? Entity => SpriteView.Entity;
|
||||
|
||||
@@ -141,6 +144,13 @@ namespace Content.Client.UserInterface.Controls
|
||||
SetSize = new Vector2(DefaultButtonSize, DefaultButtonSize),
|
||||
OverrideDirection = Direction.South
|
||||
});
|
||||
AddChild(ProtoView = new EntityPrototypeView
|
||||
{
|
||||
Visible = false,
|
||||
Scale = new Vector2(2, 2),
|
||||
SetSize = new Vector2(DefaultButtonSize, DefaultButtonSize),
|
||||
OverrideDirection = Direction.South
|
||||
});
|
||||
|
||||
AddChild(HoverSpriteView = new SpriteView
|
||||
{
|
||||
@@ -209,12 +219,35 @@ namespace Content.Client.UserInterface.Controls
|
||||
HoverSpriteView.SetEntity(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Causes the control to display a placeholder prototype, optionally faded
|
||||
/// </summary>
|
||||
public void SetEntity(EntityUid? ent)
|
||||
{
|
||||
SpriteView.SetEntity(ent);
|
||||
SpriteView.Visible = true;
|
||||
ProtoView.Visible = false;
|
||||
UpdateButtonTexture();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Causes the control to display a placeholder prototype, optionally faded
|
||||
/// </summary>
|
||||
public void SetPrototype(EntProtoId? proto, bool fade)
|
||||
{
|
||||
ProtoView.SetPrototype(proto);
|
||||
SpriteView.Visible = false;
|
||||
ProtoView.Visible = true;
|
||||
|
||||
UpdateButtonTexture();
|
||||
|
||||
if (ProtoView.Entity is not { } ent || !fade)
|
||||
return;
|
||||
|
||||
var sprites = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<SpriteSystem>();
|
||||
sprites.SetColor((ent.Owner, ent.Comp1), Color.DarkGray.WithAlpha(0.65f));
|
||||
}
|
||||
|
||||
private void UpdateButtonTexture()
|
||||
{
|
||||
var fullTexture = Theme.ResolveTextureOrNull(_fullButtonTexturePath);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<ScrollContainer HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
SizeFlagsStretchRatio="6">
|
||||
<GridContainer Name="Values"/>
|
||||
<GridContainer Name="Values" HSeparationOverride="0" VSeparationOverride="15"/>
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
|
||||
@@ -4,7 +4,6 @@ using Content.Client.Actions.UI;
|
||||
using Content.Client.Cooldown;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Content.Shared.Charges.Components;
|
||||
using Content.Shared.Charges.Systems;
|
||||
using Content.Shared.Examine;
|
||||
using Robust.Client.GameObjects;
|
||||
@@ -27,7 +26,6 @@ public sealed class ActionButton : Control, IEntityControl
|
||||
private IPlayerManager _player;
|
||||
private SpriteSystem? _spriteSys;
|
||||
private ActionUIController? _controller;
|
||||
private SharedChargesSystem _sharedChargesSys;
|
||||
private bool _beingHovered;
|
||||
private bool _depressed;
|
||||
private bool _toggled;
|
||||
@@ -71,7 +69,6 @@ public sealed class ActionButton : Control, IEntityControl
|
||||
_entities = entities;
|
||||
_player = IoCManager.Resolve<IPlayerManager>();
|
||||
_spriteSys = spriteSys;
|
||||
_sharedChargesSys = _entities.System<SharedChargesSystem>();
|
||||
_controller = controller;
|
||||
|
||||
MouseFilter = MouseFilterMode.Pass;
|
||||
|
||||
@@ -21,17 +21,20 @@ public sealed class EmotesUIController : UIController, IOnStateChanged<GameplayS
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
|
||||
private MenuButton? EmotesButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.EmotesButton;
|
||||
private SimpleRadialMenu? _menu;
|
||||
|
||||
private static readonly Dictionary<EmoteCategory, (string Tooltip, SpriteSpecifier Sprite)> EmoteGroupingInfo
|
||||
= new Dictionary<EmoteCategory, (string Tooltip, SpriteSpecifier Sprite)>
|
||||
{
|
||||
[EmoteCategory.General] = ("emote-menu-category-general", new SpriteSpecifier.Texture(new ResPath("/Textures/Clothing/Head/Soft/mimesoft.rsi/icon.png"))),
|
||||
[EmoteCategory.Hands] = ("emote-menu-category-hands", new SpriteSpecifier.Texture(new ResPath("/Textures/Clothing/Hands/Gloves/latex.rsi/icon.png"))),
|
||||
[EmoteCategory.Vocal] = ("emote-menu-category-vocal", new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/Emotes/vocal.png"))),
|
||||
};
|
||||
private static readonly Dictionary<EmoteCategory, (string Tooltip, SpriteSpecifier Sprite)> EmoteGroupingInfo =
|
||||
new()
|
||||
{
|
||||
[EmoteCategory.General] = ("emote-menu-category-general",
|
||||
new SpriteSpecifier.Rsi(new ResPath("/Textures/Clothing/Head/Soft/mimesoft.rsi"), "icon")),
|
||||
[EmoteCategory.Hands] = ("emote-menu-category-hands",
|
||||
new SpriteSpecifier.Rsi(new ResPath("/Textures/Clothing/Hands/Gloves/latex.rsi"), "icon")),
|
||||
[EmoteCategory.Vocal] = ("emote-menu-category-vocal",
|
||||
new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/Emotes/vocal.png"))),
|
||||
};
|
||||
|
||||
public void OnStateEntered(GameplayState state)
|
||||
{
|
||||
@@ -135,7 +138,7 @@ public sealed class EmotesUIController : UIController, IOnStateChanged<GameplayS
|
||||
var whitelistSystem = EntitySystemManager.GetEntitySystem<EntityWhitelistSystem>();
|
||||
var player = _playerManager.LocalSession?.AttachedEntity;
|
||||
|
||||
Dictionary<EmoteCategory, List<RadialMenuOption>> emotesByCategory = new();
|
||||
Dictionary<EmoteCategory, List<RadialMenuOption>> emotesByCategory = new();
|
||||
foreach (var emote in emotePrototypes)
|
||||
{
|
||||
if(emote.Category == EmoteCategory.Invalid)
|
||||
|
||||
@@ -12,6 +12,7 @@ using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controllers;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -73,7 +74,8 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
{
|
||||
if (entity.Owner != _player.LocalEntity)
|
||||
return;
|
||||
AddHand(name, location);
|
||||
if (_handsSystem.TryGetHand((entity.Owner, entity.Comp), name, out var hand))
|
||||
AddHand(name, hand.Value);
|
||||
}
|
||||
|
||||
private void OnRemoveHand(Entity<HandsComponent> entity, string name)
|
||||
@@ -139,7 +141,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
_playerHandsComponent = handsComp;
|
||||
foreach (var (name, hand) in handsComp.Comp.Hands)
|
||||
{
|
||||
var handButton = AddHand(name, hand.Location);
|
||||
var handButton = AddHand(name, hand);
|
||||
|
||||
if (_handsSystem.TryGetHeldItem(handsComp.AsNullable(), name, out var held) &&
|
||||
_entities.TryGetComponent(held, out VirtualItemComponent? virt))
|
||||
@@ -147,11 +149,25 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
handButton.SetEntity(virt.BlockingEntity);
|
||||
handButton.Blocked = true;
|
||||
}
|
||||
else
|
||||
else if (held != null)
|
||||
{
|
||||
handButton.SetEntity(held);
|
||||
handButton.Blocked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hand.EmptyRepresentative is { } representative)
|
||||
{
|
||||
// placeholder, view it
|
||||
SetRepresentative(handButton, representative);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise empty
|
||||
handButton.SetEntity(null);
|
||||
}
|
||||
handButton.Blocked = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (handsComp.Comp.ActiveHandId == null)
|
||||
@@ -159,6 +175,11 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
SetActiveHand(handsComp.Comp.ActiveHandId);
|
||||
}
|
||||
|
||||
private void SetRepresentative(HandButton handButton, EntProtoId prototype)
|
||||
{
|
||||
handButton.SetPrototype(prototype, true);
|
||||
}
|
||||
|
||||
private void HandBlocked(string handName)
|
||||
{
|
||||
if (!_handLookup.TryGetValue(handName, out var hand))
|
||||
@@ -203,7 +224,12 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
hand.Blocked = false;
|
||||
}
|
||||
|
||||
UpdateHandStatus(hand, entity);
|
||||
if (_playerHandsComponent != null &&
|
||||
_player.LocalSession?.AttachedEntity is { } playerEntity &&
|
||||
_handsSystem.TryGetHand((playerEntity, _playerHandsComponent), name, out var handData))
|
||||
{
|
||||
UpdateHandStatus(hand, entity, handData);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnItemRemoved(string name, EntityUid entity)
|
||||
@@ -212,8 +238,19 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
if (hand == null)
|
||||
return;
|
||||
|
||||
if (_playerHandsComponent != null &&
|
||||
_player.LocalSession?.AttachedEntity is { } playerEntity &&
|
||||
_handsSystem.TryGetHand((playerEntity, _playerHandsComponent), name, out var handData))
|
||||
{
|
||||
UpdateHandStatus(hand, null, handData);
|
||||
if (handData?.EmptyRepresentative is { } representative)
|
||||
{
|
||||
SetRepresentative(hand, representative);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
hand.SetEntity(null);
|
||||
UpdateHandStatus(hand, null);
|
||||
}
|
||||
|
||||
private HandsContainer GetFirstAvailableContainer()
|
||||
@@ -276,13 +313,13 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
if (foldedLocation == HandUILocation.Left)
|
||||
{
|
||||
_statusHandLeft = handControl;
|
||||
HandsGui.UpdatePanelEntityLeft(heldEnt);
|
||||
HandsGui.UpdatePanelEntityLeft(heldEnt, hand.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Middle or right
|
||||
_statusHandRight = handControl;
|
||||
HandsGui.UpdatePanelEntityRight(heldEnt);
|
||||
HandsGui.UpdatePanelEntityRight(heldEnt, hand.Value);
|
||||
}
|
||||
|
||||
HandsGui.SetHighlightHand(foldedLocation);
|
||||
@@ -295,9 +332,9 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
return handControl;
|
||||
}
|
||||
|
||||
private HandButton AddHand(string handName, HandLocation location)
|
||||
private HandButton AddHand(string handName, Hand hand)
|
||||
{
|
||||
var button = new HandButton(handName, location);
|
||||
var button = new HandButton(handName, hand.Location);
|
||||
button.StoragePressed += StorageActivate;
|
||||
button.Pressed += HandPressed;
|
||||
|
||||
@@ -313,10 +350,16 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
GetFirstAvailableContainer().AddButton(button);
|
||||
}
|
||||
|
||||
if (hand.EmptyRepresentative is { } representative)
|
||||
{
|
||||
SetRepresentative(button, representative);
|
||||
}
|
||||
UpdateHandStatus(button, null, hand);
|
||||
|
||||
// If we don't have a status for this hand type yet, set it.
|
||||
// This means we have status filled by default in most scenarios,
|
||||
// otherwise the user'd need to switch hands to "activate" the hands the first time.
|
||||
if (location.GetUILocation() == HandUILocation.Left)
|
||||
if (hand.Location.GetUILocation() == HandUILocation.Left)
|
||||
_statusHandLeft ??= button;
|
||||
else
|
||||
_statusHandRight ??= button;
|
||||
@@ -480,12 +523,12 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateHandStatus(HandButton hand, EntityUid? entity)
|
||||
private void UpdateHandStatus(HandButton hand, EntityUid? entity, Hand? handData)
|
||||
{
|
||||
if (hand == _statusHandLeft)
|
||||
HandsGui?.UpdatePanelEntityLeft(entity);
|
||||
HandsGui?.UpdatePanelEntityLeft(entity, handData);
|
||||
|
||||
if (hand == _statusHandRight)
|
||||
HandsGui?.UpdatePanelEntityRight(entity);
|
||||
HandsGui?.UpdatePanelEntityRight(entity, handData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,14 @@ public sealed partial class HotbarGui : UIWidget
|
||||
LayoutContainer.SetGrowVertical(this, LayoutContainer.GrowDirection.Begin);
|
||||
}
|
||||
|
||||
public void UpdatePanelEntityLeft(EntityUid? entity)
|
||||
public void UpdatePanelEntityLeft(EntityUid? entity, Hand? hand)
|
||||
{
|
||||
StatusPanelLeft.Update(entity);
|
||||
StatusPanelLeft.Update(entity, hand);
|
||||
}
|
||||
|
||||
public void UpdatePanelEntityRight(EntityUid? entity)
|
||||
public void UpdatePanelEntityRight(EntityUid? entity, Hand? hand)
|
||||
{
|
||||
StatusPanelRight.Update(entity);
|
||||
StatusPanelRight.Update(entity, hand);
|
||||
}
|
||||
|
||||
public void SetHighlightHand(HandUILocation? hand)
|
||||
|
||||
@@ -17,6 +17,7 @@ public sealed partial class ItemStatusPanel : Control
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
[ViewVariables] private EntityUid? _entity;
|
||||
[ViewVariables] private Hand? _hand;
|
||||
|
||||
// Tracked so we can re-run SetSide() if the theme changes.
|
||||
private HandUILocation _side;
|
||||
@@ -101,29 +102,45 @@ public sealed partial class ItemStatusPanel : Control
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
UpdateItemName();
|
||||
UpdateItemName(_hand);
|
||||
}
|
||||
|
||||
public void Update(EntityUid? entity)
|
||||
public void Update(EntityUid? entity, Hand? hand)
|
||||
{
|
||||
ItemNameLabel.Visible = entity != null;
|
||||
NoItemLabel.Visible = entity == null;
|
||||
if (entity == _entity && hand == _hand)
|
||||
return;
|
||||
|
||||
_hand = hand;
|
||||
if (entity == null)
|
||||
{
|
||||
ItemNameLabel.Text = "";
|
||||
ClearOldStatus();
|
||||
_entity = null;
|
||||
|
||||
if (hand?.EmptyLabel is { } label)
|
||||
{
|
||||
ItemNameLabel.Visible = true;
|
||||
NoItemLabel.Visible = false;
|
||||
|
||||
ItemNameLabel.Text = Loc.GetString(label);
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemNameLabel.Visible = false;
|
||||
NoItemLabel.Visible = true;
|
||||
|
||||
ItemNameLabel.Text = "";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity != _entity)
|
||||
{
|
||||
_entity = entity.Value;
|
||||
BuildNewEntityStatus();
|
||||
ItemNameLabel.Visible = true;
|
||||
NoItemLabel.Visible = false;
|
||||
|
||||
UpdateItemName();
|
||||
}
|
||||
_entity = entity.Value;
|
||||
BuildNewEntityStatus();
|
||||
|
||||
UpdateItemName(hand);
|
||||
}
|
||||
|
||||
public void UpdateHighlight(bool highlight)
|
||||
@@ -131,14 +148,14 @@ public sealed partial class ItemStatusPanel : Control
|
||||
HighlightPanel.Visible = highlight;
|
||||
}
|
||||
|
||||
private void UpdateItemName()
|
||||
private void UpdateItemName(Hand? hand)
|
||||
{
|
||||
if (_entity == null)
|
||||
return;
|
||||
|
||||
if (!_entityManager.TryGetComponent<MetaDataComponent>(_entity, out var meta) || meta.Deleted)
|
||||
{
|
||||
Update(null);
|
||||
Update(null, hand);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -194,8 +194,6 @@ public sealed class InventoryUIController : UIController, IOnStateEntered<Gamepl
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
int GetIndex(Vector2i position)
|
||||
{
|
||||
return position.Y * maxWidth + position.X;
|
||||
|
||||
@@ -185,12 +185,7 @@ public sealed class ItemGridPiece : Control, IEntityControl
|
||||
|
||||
handle.SetTransform(pos, iconRotation);
|
||||
var box = new UIBox2(root, root + sprite.Size * scale);
|
||||
|
||||
var ev = new BeforeRenderInGridEvent(new Color(255, 255, 255));
|
||||
_entityManager.EventBus.RaiseLocalEvent(Entity, ev);
|
||||
|
||||
handle.DrawTextureRect(sprite, box, ev.Color);
|
||||
|
||||
handle.DrawTextureRect(sprite, box);
|
||||
handle.SetTransform(GlobalPixelPosition, Angle.Zero);
|
||||
}
|
||||
else
|
||||
@@ -303,19 +298,6 @@ public sealed class ItemGridPiece : Control, IEntityControl
|
||||
public EntityUid? UiEntity => Entity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event gets raised before a sprite gets drawn in a grid and lets to change the sprite color for several gameobjects that have special sprites to render in containers.
|
||||
/// </summary>
|
||||
public sealed class BeforeRenderInGridEvent : EntityEventArgs
|
||||
{
|
||||
public Color Color { get; set; }
|
||||
|
||||
public BeforeRenderInGridEvent(Color color)
|
||||
{
|
||||
Color = color;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ItemGridPieceMarks
|
||||
{
|
||||
First,
|
||||
|
||||
@@ -10,7 +10,6 @@ using Content.Shared._CP14.Cooking.Components;
|
||||
using Content.Shared.DisplacementMap;
|
||||
using Content.Shared.Rounding;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Client._CP14.Cooking;
|
||||
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
// https://github.com/dotnet/runtime/issues/107197
|
||||
// So we can't really parallelize integration tests harder either until the runtime fixes that,
|
||||
// *or* we fix serv3 to not spam expression trees.
|
||||
[assembly: LevelOfParallelism(3)]
|
||||
[assembly: LevelOfParallelism(2)]
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using Content.Shared.Damage.Components;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.Damageable;
|
||||
|
||||
public sealed class StaminaComponentTest
|
||||
{
|
||||
[Test]
|
||||
public async Task ValidatePrototypes()
|
||||
{
|
||||
await using var pair = await PoolManager.GetServerClient();
|
||||
var server = pair.Server;
|
||||
|
||||
var protos = pair.GetPrototypesWithComponent<StaminaComponent>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
foreach (var (proto, comp) in protos)
|
||||
{
|
||||
Assert.That(comp.AnimationThreshold, Is.LessThan(comp.CritThreshold),
|
||||
$"Animation threshold on {proto.ID} must be less than its crit threshold.");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
#nullable enable
|
||||
using Content.Server.Cuffs;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Robust.Server.Console;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
|
||||
{
|
||||
@@ -22,9 +20,15 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
|
||||
components:
|
||||
- type: Cuffable
|
||||
- type: Hands
|
||||
hands:
|
||||
hand_right:
|
||||
location: Right
|
||||
hand_left:
|
||||
location: Left
|
||||
sortedHands:
|
||||
- hand_right
|
||||
- hand_left
|
||||
- type: ComplexInteraction
|
||||
- type: Body
|
||||
prototype: Human
|
||||
|
||||
- type: entity
|
||||
name: HandcuffsDummy
|
||||
@@ -47,7 +51,6 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
|
||||
HandsComponent hands = default!;
|
||||
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var mapManager = server.ResolveDependency<IMapManager>();
|
||||
var host = server.ResolveDependency<IServerConsoleHost>();
|
||||
|
||||
var map = await pair.CreateTestMap();
|
||||
@@ -73,7 +76,6 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
|
||||
{
|
||||
Assert.That(entityManager.TryGetComponent(human, out cuffed!), $"Human has no {nameof(CuffableComponent)}");
|
||||
Assert.That(entityManager.TryGetComponent(human, out hands!), $"Human has no {nameof(HandsComponent)}");
|
||||
Assert.That(entityManager.TryGetComponent(human, out BodyComponent? _), $"Human has no {nameof(BodyComponent)}");
|
||||
Assert.That(entityManager.TryGetComponent(cuffs, out HandcuffComponent? _), $"Handcuff has no {nameof(HandcuffComponent)}");
|
||||
Assert.That(entityManager.TryGetComponent(secondCuffs, out HandcuffComponent? _), $"Second handcuffs has no {nameof(HandcuffComponent)}");
|
||||
});
|
||||
|
||||
@@ -9,7 +9,6 @@ using Content.Server.Mind;
|
||||
using Content.Server.Roles;
|
||||
using Content.Server.RoundEnd;
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.FixedPoint;
|
||||
@@ -20,6 +19,7 @@ using Content.Shared.NPC.Prototypes;
|
||||
using Content.Shared.NPC.Systems;
|
||||
using Content.Shared.NukeOps;
|
||||
using Content.Shared.Pinpointer;
|
||||
using Content.Shared.Roles.Components;
|
||||
using Content.Shared.Station.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Linq;
|
||||
using Content.Server.Ghost.Roles;
|
||||
using Content.Server.Ghost.Roles.Components;
|
||||
using Content.Server.Mind;
|
||||
using Content.Server.Roles;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
using Content.Shared.FixedPoint;
|
||||
@@ -11,7 +10,7 @@ using Content.Shared.Mind;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Players;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Roles.Jobs;
|
||||
using Content.Shared.Roles.Components;
|
||||
using Robust.Server.Console;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Player;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Roles;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Roles.Jobs;
|
||||
using Content.Shared.Roles.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Reflection;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.IntegrationTests.Tests.Interaction;
|
||||
using Content.Server.Explosion.Components;
|
||||
using Content.Shared.Explosion.Components;
|
||||
using Content.Shared.Trigger.Components;
|
||||
using Content.Shared.Trigger.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
@@ -25,19 +25,19 @@ public sealed class ModularGrenadeTests : InteractionTest
|
||||
await InteractUsing(Cable);
|
||||
|
||||
// Insert & remove trigger
|
||||
AssertComp<OnUseTimerTriggerComponent>(false);
|
||||
AssertComp<TimerTriggerComponent>(false);
|
||||
await InteractUsing(Trigger);
|
||||
AssertComp<OnUseTimerTriggerComponent>();
|
||||
AssertComp<TimerTriggerComponent>();
|
||||
await FindEntity(Trigger, LookupFlags.Uncontained, shouldSucceed: false);
|
||||
await InteractUsing(Pry);
|
||||
AssertComp<OnUseTimerTriggerComponent>(false);
|
||||
AssertComp<TimerTriggerComponent>(false);
|
||||
|
||||
// Trigger was dropped to floor, not deleted.
|
||||
await FindEntity(Trigger, LookupFlags.Uncontained);
|
||||
|
||||
// Re-insert
|
||||
await InteractUsing(Trigger);
|
||||
AssertComp<OnUseTimerTriggerComponent>();
|
||||
AssertComp<TimerTriggerComponent>();
|
||||
|
||||
// Insert & remove payload.
|
||||
await InteractUsing(Payload);
|
||||
@@ -56,13 +56,14 @@ public sealed class ModularGrenadeTests : InteractionTest
|
||||
await Pickup();
|
||||
AssertComp<ActiveTimerTriggerComponent>(false);
|
||||
await UseInHand();
|
||||
AssertComp<ActiveTimerTriggerComponent>(true);
|
||||
|
||||
// So uhhh grenades in hands don't destroy themselves when exploding. Maybe that will be fixed eventually.
|
||||
await Drop();
|
||||
|
||||
// Wait until grenade explodes
|
||||
var timer = Comp<ActiveTimerTriggerComponent>();
|
||||
while (timer.TimeRemaining >= 0)
|
||||
var triggerSys = SEntMan.System<TriggerSystem>();
|
||||
while (Target != null && triggerSys.GetRemainingTime(SEntMan.GetEntity(Target.Value))?.TotalSeconds >= 0.0)
|
||||
{
|
||||
await RunTicks(10);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ using System.Linq;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Content.Server.Shuttles.Systems;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Shuttles.Components;
|
||||
using Content.Shared.Station.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map.Components;
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ public sealed class StoreTests
|
||||
|
||||
|
||||
var buyMsg = new StoreBuyListingMessage(discountedListingItem.ID){Actor = human};
|
||||
server.EntMan.EventBus.RaiseComponentEvent(pda, storeComponent, buyMsg);
|
||||
server.EntMan.EventBus.RaiseLocalEvent(pda, buyMsg);
|
||||
|
||||
var newBalance = storeComponent.Balance[UplinkSystem.TelecrystalCurrencyPrototype];
|
||||
Assert.That(newBalance.Value, Is.EqualTo((originalBalance - plainDiscountedCost).Value), "Expected to have balance reduced by discounted cost");
|
||||
@@ -141,7 +141,7 @@ public sealed class StoreTests
|
||||
Assert.That(costAfterBuy.Value, Is.EqualTo(prototypeCost.Value), "Expected cost after discount refund to be equal to prototype cost.");
|
||||
|
||||
var refundMsg = new StoreRequestRefundMessage { Actor = human };
|
||||
server.EntMan.EventBus.RaiseComponentEvent(pda, storeComponent, refundMsg);
|
||||
server.EntMan.EventBus.RaiseLocalEvent(pda, refundMsg);
|
||||
|
||||
// get refreshed item after refund re-generated items
|
||||
discountedListingItem = storeComponent.FullListingsCatalog.First(x => x.ID == itemId);
|
||||
|
||||
@@ -13,6 +13,7 @@ using Content.Server.Clothing.Systems;
|
||||
using Content.Server.Implants;
|
||||
using Content.Shared.Implants;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Lock;
|
||||
using Content.Shared.PDA;
|
||||
|
||||
namespace Content.Server.Access.Systems
|
||||
@@ -25,6 +26,7 @@ namespace Content.Server.Access.Systems
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly ChameleonClothingSystem _chameleon = default!;
|
||||
[Dependency] private readonly ChameleonControllerSystem _chamController = default!;
|
||||
[Dependency] private readonly LockSystem _lock = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -79,7 +81,8 @@ namespace Content.Server.Access.Systems
|
||||
|
||||
private void OnAfterInteract(EntityUid uid, AgentIDCardComponent component, AfterInteractEvent args)
|
||||
{
|
||||
if (args.Target == null || !args.CanReach || !TryComp<AccessComponent>(args.Target, out var targetAccess) || !HasComp<IdCardComponent>(args.Target))
|
||||
if (args.Target == null || !args.CanReach || _lock.IsLocked(uid) ||
|
||||
!TryComp<AccessComponent>(args.Target, out var targetAccess) || !HasComp<IdCardComponent>(args.Target))
|
||||
return;
|
||||
|
||||
if (!TryComp<AccessComponent>(uid, out var access) || !HasComp<IdCardComponent>(uid))
|
||||
|
||||
@@ -44,7 +44,7 @@ public sealed class VariantizeCommand : IConsoleCommand
|
||||
foreach (var tile in mapsSystem.GetAllTiles(euid.Value, gridComp))
|
||||
{
|
||||
var def = turfSystem.GetContentTileDefinition(tile);
|
||||
var newTile = new Tile(tile.Tile.TypeId, tile.Tile.Flags, tileSystem.PickVariant(def));
|
||||
var newTile = new Tile(tile.Tile.TypeId, tile.Tile.Flags, tileSystem.PickVariant(def), tile.Tile.RotationMirroring);
|
||||
mapsSystem.SetTile(euid.Value, gridComp, tile.GridIndices, newTile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Warps;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Follower;
|
||||
using Content.Shared.Ghost;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using Content.Shared.Administration.Components;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Server.Administration.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class HeadstandComponent : SharedHeadstandComponent
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration.Managers;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Forensics;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Hands.Systems;
|
||||
using Content.Server.Mind;
|
||||
@@ -21,6 +20,7 @@ using Content.Shared.PDA;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Roles.Components;
|
||||
using Content.Shared.Roles.Jobs;
|
||||
using Content.Shared.StationRecords;
|
||||
using Content.Shared.Throwing;
|
||||
|
||||
@@ -29,15 +29,16 @@ public sealed partial class AdminVerbSystem
|
||||
private static readonly EntProtoId DefaultNukeOpRule = "LoneOpsSpawn";
|
||||
private static readonly EntProtoId DefaultRevsRule = "Revolutionary";
|
||||
private static readonly EntProtoId DefaultThiefRule = "Thief";
|
||||
private static readonly EntProtoId DefaultChangelingRule = "Changeling";
|
||||
private static readonly EntProtoId ParadoxCloneRuleId = "ParadoxCloneSpawn";
|
||||
private static readonly ProtoId<StartingGearPrototype> PirateGearId = "PirateGear";
|
||||
|
||||
//CP14
|
||||
private static readonly EntProtoId CP14VampireUnnameable = "CP14GameRuleVampireClanUnnameable";
|
||||
private static readonly EntProtoId CP14VampireDevourers = "CP14GameRuleVampireClanDevourers";
|
||||
private static readonly EntProtoId CP14VampireNightChildrens = "CP14GameRuleVampireClanNightChildrens";
|
||||
//CP14 end
|
||||
|
||||
private static readonly EntProtoId ParadoxCloneRuleId = "ParadoxCloneSpawn";
|
||||
|
||||
// All antag verbs have names so invokeverb works.
|
||||
private void AddAntagVerbs(GetVerbsEvent<Verb> args)
|
||||
{
|
||||
@@ -108,7 +109,7 @@ public sealed partial class AdminVerbSystem
|
||||
_antag.ForceMakeAntag<TraitorRuleComponent>(targetPlayer, DefaultTraitorRule);
|
||||
},
|
||||
Impact = LogImpact.High,
|
||||
Message = string.Join(": ", traitorName, Loc.GetString("admin-verb-make-traitor")),
|
||||
Message = string.Join(": ", traitorName, Loc.GetString("admin-verb-make-traitor")),
|
||||
};
|
||||
args.Verbs.Add(traitor);
|
||||
|
||||
@@ -203,6 +204,21 @@ public sealed partial class AdminVerbSystem
|
||||
};
|
||||
args.Verbs.Add(thief);
|
||||
|
||||
var changelingName = Loc.GetString("admin-verb-text-make-changeling");
|
||||
Verb changeling = new()
|
||||
{
|
||||
Text = changelingName,
|
||||
Category = VerbCategory.Antag,
|
||||
Icon = new SpriteSpecifier.Rsi(new ResPath("/Textures/Objects/Weapons/Melee/armblade.rsi"), "icon"),
|
||||
Act = () =>
|
||||
{
|
||||
_antag.ForceMakeAntag<ChangelingRuleComponent>(targetPlayer, DefaultChangelingRule);
|
||||
},
|
||||
Impact = LogImpact.High,
|
||||
Message = string.Join(": ", changelingName, Loc.GetString("admin-verb-make-changeling")),
|
||||
};
|
||||
args.Verbs.Add(changeling);
|
||||
|
||||
var paradoxCloneName = Loc.GetString("admin-verb-text-make-paradox-clone");
|
||||
Verb paradox = new()
|
||||
{
|
||||
|
||||
@@ -2,15 +2,12 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Administration.Components;
|
||||
using Content.Server.Atmos;
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Cargo.Components;
|
||||
using Content.Server.Doors.Systems;
|
||||
using Content.Server.Hands.Systems;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Stack;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.Weapons.Ranged.Systems;
|
||||
using Content.Shared.Access;
|
||||
@@ -28,6 +25,7 @@ using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.PDA;
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.Station.Components;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
using Robust.Server.Physics;
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using Content.Server.AlertLevel.Systems;
|
||||
|
||||
namespace Content.Server.AlertLevel;
|
||||
/// <summary>
|
||||
/// This component is for changing the alert level of the station when triggered.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(AlertLevelChangeOnTriggerSystem))]
|
||||
public sealed partial class AlertLevelChangeOnTriggerComponent : Component
|
||||
{
|
||||
///<summary>
|
||||
///The alert level to change to when triggered.
|
||||
///</summary>
|
||||
[DataField]
|
||||
public string Level = "blue";
|
||||
|
||||
/// <summary>
|
||||
///Whether to play the sound when the alert level changes.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool PlaySound = true;
|
||||
|
||||
/// <summary>
|
||||
///Whether to say the announcement when the alert level changes.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool Announce = true;
|
||||
|
||||
/// <summary>
|
||||
///Force the alert change. This applies if the alert level is not selectable or not.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool Force = false;
|
||||
}
|
||||
@@ -5,13 +5,13 @@ using Content.Server.Animals.Components;
|
||||
using Content.Server.Mind;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Radio;
|
||||
using Content.Server.Speech;
|
||||
using Content.Server.Speech.Components;
|
||||
using Content.Server.Vocalization.Systems;
|
||||
using Content.Shared.Animals.Components;
|
||||
using Content.Shared.Animals.Systems;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Speech;
|
||||
using Content.Shared.Speech.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Random;
|
||||
@@ -25,7 +25,7 @@ namespace Content.Server.Animals.Systems;
|
||||
/// (radiovocalizer) and stores them in a list. When an entity with a VocalizerComponent attempts to vocalize, this will
|
||||
/// try to set the message from memory.
|
||||
/// </summary>
|
||||
public sealed partial class ParrotMemorySystem : EntitySystem
|
||||
public sealed partial class ParrotMemorySystem : SharedParrotMemorySystem
|
||||
{
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
@@ -42,8 +42,6 @@ public sealed partial class ParrotMemorySystem : EntitySystem
|
||||
|
||||
SubscribeLocalEvent<EraseEvent>(OnErase);
|
||||
|
||||
SubscribeLocalEvent<ParrotMemoryComponent, GetVerbsEvent<Verb>>(OnGetVerbs);
|
||||
|
||||
SubscribeLocalEvent<ParrotListenerComponent, MapInitEvent>(ListenerOnMapInit);
|
||||
|
||||
SubscribeLocalEvent<ParrotListenerComponent, ListenEvent>(OnListen);
|
||||
@@ -57,30 +55,6 @@ public sealed partial class ParrotMemorySystem : EntitySystem
|
||||
DeletePlayerMessages(args.PlayerNetUserId);
|
||||
}
|
||||
|
||||
private void OnGetVerbs(Entity<ParrotMemoryComponent> entity, ref GetVerbsEvent<Verb> args)
|
||||
{
|
||||
var user = args.User;
|
||||
|
||||
// limit this to admins
|
||||
if (!_admin.IsAdmin(user))
|
||||
return;
|
||||
|
||||
// simple verb that just clears the memory list
|
||||
var clearMemoryVerb = new Verb()
|
||||
{
|
||||
Text = Loc.GetString("parrot-verb-clear-memory"),
|
||||
Category = VerbCategory.Admin,
|
||||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/clear-parrot.png")),
|
||||
Act = () =>
|
||||
{
|
||||
entity.Comp.SpeechMemories.Clear();
|
||||
_popup.PopupEntity(Loc.GetString("parrot-popup-memory-cleared"), entity, user, PopupType.Medium);
|
||||
},
|
||||
};
|
||||
|
||||
args.Verbs.Add(clearMemoryVerb);
|
||||
}
|
||||
|
||||
private void ListenerOnMapInit(Entity<ParrotListenerComponent> entity, ref MapInitEvent args)
|
||||
{
|
||||
// If an entity has a ParrotListenerComponent it really ought to have an ActiveListenerComponent
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Content.Server.Anomaly.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Shared.Anomaly;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Materials;
|
||||
@@ -164,8 +163,7 @@ public sealed partial class AnomalySystem
|
||||
var xform = Transform(uid);
|
||||
|
||||
if (_station.GetStationInMap(xform.MapID) is not { } station ||
|
||||
!TryComp<StationDataComponent>(station, out var data) ||
|
||||
_station.GetLargestGrid(data) is not { } grid)
|
||||
_station.GetLargestGrid(station) is not { } grid)
|
||||
{
|
||||
if (xform.GridUid == null)
|
||||
return;
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
using Content.Shared.Atmos.EntitySystems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Content.Server.Atmos.Piping.EntitySystems;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Shared.Atmos.Components;
|
||||
namespace Content.Server.Atmos.Piping.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[AutoGenerateComponentState]
|
||||
[RegisterComponent]
|
||||
public sealed partial class AtmosPipeColorComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
[AutoNetworkedField]
|
||||
public Color Color { get; set; } = Color.White;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), UsedImplicitly]
|
||||
public Color ColorVV
|
||||
{
|
||||
get => Color;
|
||||
set => IoCManager.Resolve<IEntityManager>().System<AtmosPipeColorSystem>().SetColor((Owner, this), value);
|
||||
set => IoCManager.Resolve<IEntityManager>().System<AtmosPipeColorSystem>().SetColor(Owner, this, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using Content.Server.Atmos.Piping.Components;
|
||||
using Content.Shared.Atmos.Piping;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
namespace Content.Server.Atmos.Piping.EntitySystems
|
||||
{
|
||||
public sealed class AtmosPipeColorSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<AtmosPipeColorComponent, ComponentStartup>(OnStartup);
|
||||
SubscribeLocalEvent<AtmosPipeColorComponent, ComponentShutdown>(OnShutdown);
|
||||
}
|
||||
|
||||
private void OnStartup(EntityUid uid, AtmosPipeColorComponent component, ComponentStartup args)
|
||||
{
|
||||
if (!TryComp(uid, out AppearanceComponent? appearance))
|
||||
return;
|
||||
|
||||
_appearance.SetData(uid, PipeColorVisuals.Color, component.Color, appearance);
|
||||
}
|
||||
|
||||
private void OnShutdown(EntityUid uid, AtmosPipeColorComponent component, ComponentShutdown args)
|
||||
{
|
||||
if (!TryComp(uid, out AppearanceComponent? appearance))
|
||||
return;
|
||||
|
||||
_appearance.SetData(uid, PipeColorVisuals.Color, Color.White, appearance);
|
||||
}
|
||||
|
||||
public void SetColor(EntityUid uid, AtmosPipeColorComponent component, Color color)
|
||||
{
|
||||
component.Color = color;
|
||||
|
||||
if (!TryComp(uid, out AppearanceComponent? appearance))
|
||||
return;
|
||||
|
||||
_appearance.SetData(uid, PipeColorVisuals.Color, color, appearance);
|
||||
|
||||
var ev = new AtmosPipeColorChangedEvent(color);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,46 @@
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Ghost.Components;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Events;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Pointing;
|
||||
|
||||
namespace Content.Server.Body.Systems
|
||||
namespace Content.Server.Body.Systems;
|
||||
|
||||
public sealed class BrainSystem : EntitySystem
|
||||
{
|
||||
public sealed class BrainSystem : EntitySystem
|
||||
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
|
||||
base.Initialize();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<BrainComponent, OrganAddedToBodyEvent>((uid, _, args) => HandleMind(args.Body, uid));
|
||||
SubscribeLocalEvent<BrainComponent, OrganRemovedFromBodyEvent>((uid, _, args) => HandleMind(uid, args.OldBody));
|
||||
SubscribeLocalEvent<BrainComponent, PointAttemptEvent>(OnPointAttempt);
|
||||
}
|
||||
|
||||
SubscribeLocalEvent<BrainComponent, OrganAddedToBodyEvent>((uid, _, args) => HandleMind(args.Body, uid));
|
||||
SubscribeLocalEvent<BrainComponent, OrganRemovedFromBodyEvent>((uid, _, args) => HandleMind(uid, args.OldBody));
|
||||
SubscribeLocalEvent<BrainComponent, PointAttemptEvent>(OnPointAttempt);
|
||||
}
|
||||
private void HandleMind(EntityUid newEntity, EntityUid oldEntity)
|
||||
{
|
||||
if (TerminatingOrDeleted(newEntity) || TerminatingOrDeleted(oldEntity))
|
||||
return;
|
||||
|
||||
private void HandleMind(EntityUid newEntity, EntityUid oldEntity)
|
||||
{
|
||||
if (TerminatingOrDeleted(newEntity) || TerminatingOrDeleted(oldEntity))
|
||||
return;
|
||||
EnsureComp<MindContainerComponent>(newEntity);
|
||||
EnsureComp<MindContainerComponent>(oldEntity);
|
||||
|
||||
EnsureComp<MindContainerComponent>(newEntity);
|
||||
EnsureComp<MindContainerComponent>(oldEntity);
|
||||
var ghostOnMove = EnsureComp<GhostOnMoveComponent>(newEntity);
|
||||
ghostOnMove.MustBeDead = HasComp<MobStateComponent>(newEntity); // Don't ghost living players out of their bodies.
|
||||
|
||||
var ghostOnMove = EnsureComp<GhostOnMoveComponent>(newEntity);
|
||||
if (HasComp<BodyComponent>(newEntity))
|
||||
ghostOnMove.MustBeDead = true;
|
||||
if (!_mindSystem.TryGetMind(oldEntity, out var mindId, out var mind))
|
||||
return;
|
||||
|
||||
if (!_mindSystem.TryGetMind(oldEntity, out var mindId, out var mind))
|
||||
return;
|
||||
_mindSystem.TransferTo(mindId, newEntity, mind: mind);
|
||||
}
|
||||
|
||||
_mindSystem.TransferTo(mindId, newEntity, mind: mind);
|
||||
}
|
||||
|
||||
private void OnPointAttempt(Entity<BrainComponent> ent, ref PointAttemptEvent args)
|
||||
{
|
||||
args.Cancel();
|
||||
}
|
||||
private void OnPointAttempt(Entity<BrainComponent> ent, ref PointAttemptEvent args)
|
||||
{
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Shared.Cargo;
|
||||
using Content.Shared.Cargo.Components;
|
||||
using Content.Shared.Cargo.Prototypes;
|
||||
using Content.Shared.Station.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Cargo.Components;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Server.Cargo.Components;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Shared.Cargo;
|
||||
using Content.Shared.Cargo.BUI;
|
||||
using Content.Shared.Cargo.Components;
|
||||
@@ -13,8 +12,8 @@ using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Labels.Components;
|
||||
using Content.Shared.Paper;
|
||||
using Content.Shared.Station.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -3,11 +3,11 @@ using System.Linq;
|
||||
using Content.Server.Cargo.Components;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Shared.Cargo;
|
||||
using Content.Shared.Cargo.Components;
|
||||
using Content.Shared.DeviceLinking;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.Station.Components;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -92,19 +92,22 @@ public sealed class PricingSystem : EntitySystem
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!TryComp<BodyComponent>(uid, out var body) || !TryComp<MobStateComponent>(uid, out var state))
|
||||
if (!TryComp<MobStateComponent>(uid, out var state))
|
||||
{
|
||||
Log.Error($"Tried to get the mob price of {ToPrettyString(uid)}, which has no {nameof(BodyComponent)} and no {nameof(MobStateComponent)}.");
|
||||
Log.Error($"Tried to get the mob price of {ToPrettyString(uid)}, which has no {nameof(MobStateComponent)}.");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Better handling of missing.
|
||||
var partList = _bodySystem.GetBodyChildren(uid, body).ToList();
|
||||
var totalPartsPresent = partList.Sum(_ => 1);
|
||||
var totalParts = partList.Count;
|
||||
var partPenalty = 0.0;
|
||||
if (TryComp<BodyComponent>(uid, out var body))
|
||||
{
|
||||
var partList = _bodySystem.GetBodyChildren(uid, body).ToList();
|
||||
var totalPartsPresent = partList.Sum(_ => 1);
|
||||
var totalParts = partList.Count;
|
||||
|
||||
var partRatio = totalPartsPresent / (double) totalParts;
|
||||
var partPenalty = component.Price * (1 - partRatio) * component.MissingBodyPartPenalty;
|
||||
var partRatio = totalPartsPresent / (double) totalParts;
|
||||
partPenalty = component.Price * (1 - partRatio) * component.MissingBodyPartPenalty;
|
||||
}
|
||||
|
||||
args.Price += (component.Price - partPenalty) * (_mobStateSystem.IsAlive(uid, state) ? 1.0 : component.DeathPenalty);
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
using Content.Shared.Dataset;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Chat;
|
||||
|
||||
/// <summary>
|
||||
/// Makes the entity speak when triggered. If the item has UseDelay component, the system will respect that cooldown.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class SpeakOnTriggerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The identifier for the dataset prototype containing messages to be spoken by this entity.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public ProtoId<LocalizedDatasetPrototype> Pack = string.Empty;
|
||||
}
|
||||
@@ -67,6 +67,9 @@ public sealed class SuicideSystem : EntitySystem
|
||||
if (!suicideGhostEvent.Handled || _tagSystem.HasTag(victim, CannotSuicideTag))
|
||||
return false;
|
||||
|
||||
// TODO: fix this
|
||||
// This is a handled event, but the result is never used
|
||||
// It looks like TriggerOnMobstateChange is supposed to prevent you from suiciding
|
||||
var suicideEvent = new SuicideEvent(victim);
|
||||
RaiseLocalEvent(victim, suicideEvent);
|
||||
|
||||
|
||||
105
Content.Server/Chat/Systems/ChatNotificationSystem.cs
Normal file
105
Content.Server/Chat/Systems/ChatNotificationSystem.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Chat.Prototypes;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server.Chat.Systems;
|
||||
|
||||
/// <summary>
|
||||
/// This system is used to notify specific players of the occurance of predefined events.
|
||||
/// </summary>
|
||||
public sealed partial class ChatNotificationSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IChatManager _chats = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
[Dependency] private readonly SharedRoleSystem _roles = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
// The following data does not need to be saved
|
||||
|
||||
// Local cache for rate limiting chat notifications by source
|
||||
// (Recipient, ChatNotification) -> Dictionary<Source, next allowed TOA>
|
||||
private readonly Dictionary<(EntityUid, ProtoId<ChatNotificationPrototype>), Dictionary<EntityUid, TimeSpan>> _chatNotificationsBySource = new();
|
||||
|
||||
// Local cache for rate limiting chat notifications by type
|
||||
// (Recipient, ChatNotification) -> next allowed TOA
|
||||
private readonly Dictionary<(EntityUid, ProtoId<ChatNotificationPrototype>), TimeSpan> _chatNotificationsByType = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ActorComponent, ChatNotificationEvent>(OnChatNotification);
|
||||
|
||||
_sawmill = _logManager.GetSawmill("chatnotification");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the specified player recieves a chat notification event.
|
||||
/// </summary>
|
||||
/// <param name="ent">The player receiving the chat notification.</param>
|
||||
/// <param name="args">The chat notification event</param>
|
||||
public void OnChatNotification(Entity<ActorComponent> ent, ref ChatNotificationEvent args)
|
||||
{
|
||||
if (!_proto.TryIndex(args.ChatNotification, out var chatNotification))
|
||||
{
|
||||
_sawmill.Warning("Attempted to index ChatNotificationPrototype " + args.ChatNotification + " but the prototype does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
var source = args.Source;
|
||||
var playerNotification = (ent, args.ChatNotification);
|
||||
|
||||
// Exit without notifying the player if we received a notification before the appropriate time has elasped
|
||||
|
||||
if (chatNotification.NotifyBySource)
|
||||
{
|
||||
if (!_chatNotificationsBySource.TryGetValue(playerNotification, out var trackedSources))
|
||||
trackedSources = new();
|
||||
|
||||
trackedSources.TryGetValue(source, out var timeSpan);
|
||||
trackedSources[source] = _timing.CurTime + chatNotification.NextDelay;
|
||||
|
||||
_chatNotificationsBySource[playerNotification] = trackedSources;
|
||||
|
||||
if (_timing.CurTime < timeSpan)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_chatNotificationsByType.TryGetValue(playerNotification, out var timeSpan);
|
||||
_chatNotificationsByType[playerNotification] = _timing.CurTime + chatNotification.NextDelay;
|
||||
|
||||
if (_timing.CurTime < timeSpan)
|
||||
return;
|
||||
}
|
||||
|
||||
var sourceName = args.SourceNameOverride ?? Name(source);
|
||||
var userName = args.UserNameOverride ?? (args.User.HasValue ? Name(args.User.Value) : string.Empty);
|
||||
var targetName = Name(ent);
|
||||
|
||||
var message = Loc.GetString(chatNotification.Message, ("source", sourceName), ("user", userName), ("target", targetName));
|
||||
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message));
|
||||
|
||||
_chats.ChatMessageToOne(
|
||||
ChatChannel.Notifications,
|
||||
message,
|
||||
wrappedMessage,
|
||||
default,
|
||||
false,
|
||||
ent.Comp.PlayerSession.Channel,
|
||||
colorOverride: chatNotification.Color
|
||||
);
|
||||
|
||||
if (chatNotification.Sound != null && _mind.TryGetMind(ent, out var mindId, out _))
|
||||
_roles.MindPlaySound(mindId, chatNotification.Sound);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ using Content.Server.GameTicking;
|
||||
using Content.Server.Speech.Prototypes;
|
||||
using Content.Server.Speech.EntitySystems;
|
||||
using Content.Server.Speech.Prototypes;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.Administration;
|
||||
@@ -23,6 +22,7 @@ using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Players;
|
||||
using Content.Shared.Players.RateLimiting;
|
||||
using Content.Shared.Radio;
|
||||
using Content.Shared.Station.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Audio;
|
||||
@@ -62,11 +62,6 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
[Dependency] private readonly ExamineSystemShared _examineSystem = default!;
|
||||
|
||||
public const int VoiceRange = 10; // how far voice goes in world units
|
||||
public const int WhisperClearRange = 2; // how far whisper goes while still being understandable, in world units
|
||||
public const int WhisperMuffledRange = 5; // how far whisper goes at all, in world units
|
||||
public const string DefaultAnnouncementSound = "/Audio/_CP14/Announce/event_boom.ogg"; //CP14 replaced default sound
|
||||
|
||||
private bool _loocEnabled = true;
|
||||
private bool _deadLoocEnabled;
|
||||
private bool _critLoocEnabled;
|
||||
@@ -194,13 +189,6 @@ public sealed partial class ChatSystem : SharedChatSystem
|
||||
if (!CanSendInGame(message, shell, player))
|
||||
return;
|
||||
|
||||
//CP14 Prevent god from default speaking. In waiting of chatcode refactor
|
||||
var ev = new CP14SpokeAttemptEvent(message, desiredType, player);
|
||||
RaiseLocalEvent(source, ev);
|
||||
if (ev.Cancelled)
|
||||
return;
|
||||
//CP14 end
|
||||
|
||||
ignoreActionBlocker = CheckIgnoreSpeechBlocker(source, ignoreActionBlocker);
|
||||
|
||||
// this method is a disaster
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
using Content.Server.Forensics;
|
||||
using Content.Server.Speech.EntitySystems;
|
||||
using Content.Shared.Cloning.Events;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Labels.Components;
|
||||
using Content.Shared.Labels.EntitySystems;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Paper;
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.Speech.Components;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Store;
|
||||
using Content.Shared.Store.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -13,47 +18,58 @@ using Robust.Shared.Prototypes;
|
||||
namespace Content.Server.Cloning;
|
||||
|
||||
/// <summary>
|
||||
/// The part of item cloning responsible for copying over important components.
|
||||
/// This is used for <see cref="CopyItem"/>.
|
||||
/// Anything not copied over here gets reverted to the values the item had in its prototype.
|
||||
/// The part of item cloning responsible for copying over important components.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method of copying items is of course not perfect as we cannot clone every single component, which would be pretty much impossible with our ECS.
|
||||
/// We only consider the most important components so the paradox clone gets similar equipment.
|
||||
/// This method of using subscriptions was chosen to make it easy for forks to add their own custom components that need to be copied.
|
||||
/// These are all not part of their corresponding systems because we don't want systems every system to depend on a CloningSystem namespace import, which is still heavily coupled to med code.
|
||||
/// TODO: Create a more generic "CopyEntity" method/event (probably in RT) that doesn't have this problem and then move all these subscriptions.
|
||||
/// </remarks>
|
||||
public sealed partial class CloningSystem : EntitySystem
|
||||
public sealed partial class CloningSystem
|
||||
{
|
||||
[Dependency] private readonly SharedStackSystem _stack = default!;
|
||||
[Dependency] private readonly LabelSystem _label = default!;
|
||||
[Dependency] private readonly ForensicsSystem _forensics = default!;
|
||||
[Dependency] private readonly PaperSystem _paper = default!;
|
||||
[Dependency] private readonly VocalSystem _vocal = default!;
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<StackComponent, CloningItemEvent>(OnCloneStack);
|
||||
SubscribeLocalEvent<LabelComponent, CloningItemEvent>(OnCloneLabel);
|
||||
SubscribeLocalEvent<PaperComponent, CloningItemEvent>(OnClonePaper);
|
||||
SubscribeLocalEvent<ForensicsComponent, CloningItemEvent>(OnCloneForensics);
|
||||
SubscribeLocalEvent<StoreComponent, CloningItemEvent>(OnCloneStore);
|
||||
// These are used for <see cref="CopyItem"/>.
|
||||
// Anything not copied over here gets reverted to the values the item had in its prototype.
|
||||
// This method of copying items is of course not perfect as we cannot clone every single component, which would be pretty much impossible with our ECS.
|
||||
// We only consider the most important components so the paradox clone gets similar equipment.
|
||||
// This method of using subscriptions was chosen to make it easy for forks to add their own custom components that need to be copied.
|
||||
SubscribeLocalEvent<StackComponent, CloningItemEvent>(OnCloneItemStack);
|
||||
SubscribeLocalEvent<LabelComponent, CloningItemEvent>(OnCloneItemLabel);
|
||||
SubscribeLocalEvent<PaperComponent, CloningItemEvent>(OnCloneItemPaper);
|
||||
SubscribeLocalEvent<ForensicsComponent, CloningItemEvent>(OnCloneItemForensics);
|
||||
SubscribeLocalEvent<StoreComponent, CloningItemEvent>(OnCloneItemStore);
|
||||
|
||||
// These are for cloning components that cannot be cloned using CopyComp.
|
||||
// Put them into CloningSettingsPrototype.EventComponents to have them be applied to the clone.
|
||||
SubscribeLocalEvent<VocalComponent, CloningEvent>(OnCloneVocal);
|
||||
SubscribeLocalEvent<StorageComponent, CloningEvent>(OnCloneStorage);
|
||||
SubscribeLocalEvent<InventoryComponent, CloningEvent>(OnCloneInventory);
|
||||
SubscribeLocalEvent<MovementSpeedModifierComponent, CloningEvent>(OnCloneInventory);
|
||||
}
|
||||
|
||||
private void OnCloneStack(Entity<StackComponent> ent, ref CloningItemEvent args)
|
||||
private void OnCloneItemStack(Entity<StackComponent> ent, ref CloningItemEvent args)
|
||||
{
|
||||
// if the clone is a stack as well, adjust the count of the copy
|
||||
if (TryComp<StackComponent>(args.CloneUid, out var cloneStackComp))
|
||||
_stack.SetCount(args.CloneUid, ent.Comp.Count, cloneStackComp);
|
||||
}
|
||||
|
||||
private void OnCloneLabel(Entity<LabelComponent> ent, ref CloningItemEvent args)
|
||||
private void OnCloneItemLabel(Entity<LabelComponent> ent, ref CloningItemEvent args)
|
||||
{
|
||||
// copy the label
|
||||
_label.Label(args.CloneUid, ent.Comp.CurrentLabel);
|
||||
}
|
||||
|
||||
private void OnClonePaper(Entity<PaperComponent> ent, ref CloningItemEvent args)
|
||||
private void OnCloneItemPaper(Entity<PaperComponent> ent, ref CloningItemEvent args)
|
||||
{
|
||||
// copy the text and any stamps
|
||||
if (TryComp<PaperComponent>(args.CloneUid, out var clonePaperComp))
|
||||
@@ -63,13 +79,13 @@ public sealed partial class CloningSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCloneForensics(Entity<ForensicsComponent> ent, ref CloningItemEvent args)
|
||||
private void OnCloneItemForensics(Entity<ForensicsComponent> ent, ref CloningItemEvent args)
|
||||
{
|
||||
// copy any forensics to the cloned item
|
||||
_forensics.CopyForensicsFrom(ent.Comp, args.CloneUid);
|
||||
}
|
||||
|
||||
private void OnCloneStore(Entity<StoreComponent> ent, ref CloningItemEvent args)
|
||||
private void OnCloneItemStore(Entity<StoreComponent> ent, ref CloningItemEvent args)
|
||||
{
|
||||
// copy the current amount of currency in the store
|
||||
// at the moment this takes care of uplink implants and the portable nukie uplinks
|
||||
@@ -80,4 +96,35 @@ public sealed partial class CloningSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCloneVocal(Entity<VocalComponent> ent, ref CloningEvent args)
|
||||
{
|
||||
if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name))
|
||||
return;
|
||||
|
||||
_vocal.CopyComponent(ent.AsNullable(), args.CloneUid);
|
||||
}
|
||||
|
||||
private void OnCloneStorage(Entity<StorageComponent> ent, ref CloningEvent args)
|
||||
{
|
||||
if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name))
|
||||
return;
|
||||
|
||||
_storage.CopyComponent(ent.AsNullable(), args.CloneUid);
|
||||
}
|
||||
|
||||
private void OnCloneInventory(Entity<InventoryComponent> ent, ref CloningEvent args)
|
||||
{
|
||||
if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name))
|
||||
return;
|
||||
|
||||
_inventory.CopyComponent(ent.AsNullable(), args.CloneUid);
|
||||
}
|
||||
|
||||
private void OnCloneInventory(Entity<MovementSpeedModifierComponent> ent, ref CloningEvent args)
|
||||
{
|
||||
if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name))
|
||||
return;
|
||||
|
||||
_movementSpeedModifier.CopyComponent(ent.AsNullable(), args.CloneUid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Content.Server.Cloning;
|
||||
/// System responsible for making a copy of a humanoid's body.
|
||||
/// For the cloning machines themselves look at CloningPodSystem, CloningConsoleSystem and MedicalScannerSystem instead.
|
||||
/// </summary>
|
||||
public sealed partial class CloningSystem : EntitySystem
|
||||
public sealed partial class CloningSystem : SharedCloningSystem
|
||||
{
|
||||
[Dependency] private readonly HumanoidAppearanceSystem _humanoidSystem = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
@@ -84,13 +84,7 @@ public sealed partial class CloningSystem : EntitySystem
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy components from one entity to another based on a CloningSettingsPrototype.
|
||||
/// </summary>
|
||||
/// <param name="original">The orignal Entity to clone components from.</param>
|
||||
/// <param name="clone">The target Entity to clone components to.</param>
|
||||
/// <param name="settings">The clone settings prototype containing the list of components to clone.</param>
|
||||
public void CloneComponents(EntityUid original, EntityUid clone, CloningSettingsPrototype settings)
|
||||
public override void CloneComponents(EntityUid original, EntityUid clone, CloningSettingsPrototype settings)
|
||||
{
|
||||
var componentsToCopy = settings.Components;
|
||||
var componentsToEvent = settings.EventComponents;
|
||||
@@ -128,7 +122,8 @@ public sealed partial class CloningSystem : EntitySystem
|
||||
}
|
||||
|
||||
// If the original does not have the component, then the clone shouldn't have it either.
|
||||
RemComp(clone, componentRegistration.Type);
|
||||
if (!HasComp(original, componentRegistration.Type))
|
||||
RemComp(clone, componentRegistration.Type);
|
||||
}
|
||||
|
||||
var cloningEv = new CloningEvent(settings, clone);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Shared.Station.Components;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
namespace Content.Server.Commands;
|
||||
|
||||
@@ -276,8 +276,8 @@ namespace Content.Server.Construction
|
||||
if(!insertStep.EntityValid(insert, EntityManager, Factory))
|
||||
return HandleResult.False;
|
||||
|
||||
// Unremovable items can't be inserted, unless they are a lingering stack
|
||||
if(HasComp<UnremoveableComponent>(insert) && (!TryComp<StackComponent>(insert, out var comp) || !comp.Lingering))
|
||||
// Unremovable items can't be inserted
|
||||
if(HasComp<UnremoveableComponent>(insert))
|
||||
return HandleResult.False;
|
||||
|
||||
// If we're only testing whether this step would be handled by the given event, then we're done.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.EUI;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.StationRecords;
|
||||
using Content.Server.StationRecords.Systems;
|
||||
@@ -10,12 +9,12 @@ using Content.Shared.CCVar;
|
||||
using Content.Shared.CrewManifest;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Station.Components;
|
||||
using Content.Shared.StationRecords;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.CrewManifest;
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
using Content.Server.Explosion.EntitySystems;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Components;
|
||||
|
||||
namespace Content.Server.Damage.Systems;
|
||||
|
||||
// System for damage that occurs on specific trigger, towards the user..
|
||||
public sealed class DamageUserOnTriggerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<DamageUserOnTriggerComponent, TriggerEvent>(OnTrigger);
|
||||
}
|
||||
|
||||
private void OnTrigger(EntityUid uid, DamageUserOnTriggerComponent component, TriggerEvent args)
|
||||
{
|
||||
if (args.User is null)
|
||||
return;
|
||||
|
||||
args.Handled |= OnDamageTrigger(uid, args.User.Value, component);
|
||||
}
|
||||
|
||||
private bool OnDamageTrigger(EntityUid source, EntityUid target, DamageUserOnTriggerComponent? component = null)
|
||||
{
|
||||
if (!Resolve(source, ref component))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var damage = new DamageSpecifier(component.Damage);
|
||||
var ev = new BeforeDamageUserOnTriggerEvent(damage, target);
|
||||
RaiseLocalEvent(source, ev);
|
||||
|
||||
return _damageableSystem.TryChangeDamage(target, ev.Damage, component.IgnoreResistances, origin: source) is not null;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class BeforeDamageUserOnTriggerEvent : EntityEventArgs
|
||||
{
|
||||
public DamageSpecifier Damage { get; set; }
|
||||
public EntityUid Tripper { get; }
|
||||
|
||||
public BeforeDamageUserOnTriggerEvent(DamageSpecifier damage, EntityUid target)
|
||||
{
|
||||
Damage = damage;
|
||||
Tripper = target;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Server.Defusable.Components;
|
||||
using Content.Server.Explosion.Components;
|
||||
using Content.Server.Explosion.EntitySystems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Wires;
|
||||
@@ -8,13 +7,13 @@ using Content.Shared.Construction.Components;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Defusable;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Explosion.Components;
|
||||
using Content.Shared.Explosion.Components.OnTrigger;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Trigger.Components;
|
||||
using Content.Shared.Trigger.Components.Effects;
|
||||
using Content.Shared.Trigger.Systems;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Wires;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
|
||||
namespace Content.Server.Defusable.Systems;
|
||||
@@ -74,12 +73,13 @@ public sealed class DefusableSystem : SharedDefusableSystem
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("defusable-examine-defused", ("name", uid)));
|
||||
}
|
||||
else if (comp.Activated && TryComp<ActiveTimerTriggerComponent>(uid, out var activeComp))
|
||||
else if (comp.Activated)
|
||||
{
|
||||
if (comp.DisplayTime)
|
||||
var remaining = _trigger.GetRemainingTime(uid);
|
||||
if (comp.DisplayTime && remaining != null)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("defusable-examine-live", ("name", uid),
|
||||
("time", MathF.Floor(activeComp.TimeRemaining))));
|
||||
("time", Math.Floor(remaining.Value.TotalSeconds))));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -139,16 +139,9 @@ public sealed class DefusableSystem : SharedDefusableSystem
|
||||
SetActivated(comp, true);
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("defusable-popup-begun", ("name", uid)), uid);
|
||||
if (TryComp<OnUseTimerTriggerComponent>(uid, out var timerTrigger))
|
||||
if (TryComp<TimerTriggerComponent>(uid, out var timerTrigger))
|
||||
{
|
||||
_trigger.HandleTimerTrigger(
|
||||
uid,
|
||||
user,
|
||||
timerTrigger.Delay,
|
||||
timerTrigger.BeepInterval,
|
||||
timerTrigger.InitialBeepDelay,
|
||||
timerTrigger.BeepSound
|
||||
);
|
||||
_trigger.ActivateTimerTrigger((uid, timerTrigger));
|
||||
}
|
||||
|
||||
RaiseLocalEvent(uid, new BombArmedEvent(uid));
|
||||
@@ -168,7 +161,7 @@ public sealed class DefusableSystem : SharedDefusableSystem
|
||||
|
||||
RaiseLocalEvent(uid, new BombDetonatedEvent(uid));
|
||||
|
||||
_explosion.TriggerExplosive(uid, user:detonator);
|
||||
_explosion.TriggerExplosive(uid, user: detonator);
|
||||
QueueDel(uid);
|
||||
|
||||
_appearance.SetData(uid, DefusableVisuals.Active, comp.Activated);
|
||||
@@ -188,7 +181,7 @@ public sealed class DefusableSystem : SharedDefusableSystem
|
||||
{
|
||||
SetUsable(comp, false);
|
||||
RemComp<ExplodeOnTriggerComponent>(uid);
|
||||
RemComp<OnUseTimerTriggerComponent>(uid);
|
||||
RemComp<TimerTriggerComponent>(uid);
|
||||
}
|
||||
RemComp<ActiveTimerTriggerComponent>(uid);
|
||||
|
||||
@@ -246,7 +239,7 @@ public sealed class DefusableSystem : SharedDefusableSystem
|
||||
if (comp is not { Activated: true, DelayWireUsed: false })
|
||||
return;
|
||||
|
||||
_trigger.TryDelay(wire.Owner, 30f);
|
||||
_trigger.TryDelay(wire.Owner, TimeSpan.FromSeconds(30));
|
||||
_popup.PopupEntity(Loc.GetString("defusable-popup-wire-chirp", ("name", wire.Owner)), wire.Owner);
|
||||
comp.DelayWireUsed = true;
|
||||
}
|
||||
@@ -268,7 +261,7 @@ public sealed class DefusableSystem : SharedDefusableSystem
|
||||
if (comp is { Activated: true, ProceedWireUsed: false })
|
||||
{
|
||||
comp.ProceedWireUsed = true;
|
||||
_trigger.TryDelay(wire.Owner, -15f);
|
||||
_trigger.TryDelay(wire.Owner, TimeSpan.FromSeconds(-15));
|
||||
}
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("defusable-popup-wire-proceed-pulse", ("name", wire.Owner)), wire.Owner);
|
||||
@@ -298,7 +291,7 @@ public sealed class DefusableSystem : SharedDefusableSystem
|
||||
{
|
||||
if (!comp.ActivatedWireUsed)
|
||||
{
|
||||
_trigger.TryDelay(wire.Owner, 30f);
|
||||
_trigger.TryDelay(wire.Owner, TimeSpan.FromSeconds(30));
|
||||
_popup.PopupEntity(Loc.GetString("defusable-popup-wire-chirp", ("name", wire.Owner)), wire.Owner);
|
||||
comp.ActivatedWireUsed = true;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Body.Systems;
|
||||
@@ -14,15 +15,13 @@ using Content.Shared.Damage;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Destructible;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Trigger.Systems;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using System.Linq;
|
||||
using Content.Shared.Humanoid;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.Destructible
|
||||
{
|
||||
|
||||
@@ -5,6 +5,6 @@ public sealed partial class TimerStartBehavior : IThresholdBehavior
|
||||
{
|
||||
public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
|
||||
{
|
||||
system.TriggerSystem.StartTimer(owner, cause);
|
||||
system.TriggerSystem.ActivateTimerTrigger(owner, cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
namespace Content.Server.Destructible.Thresholds.Behaviors;
|
||||
using Content.Shared.Trigger.Systems;
|
||||
|
||||
namespace Content.Server.Destructible.Thresholds.Behaviors;
|
||||
|
||||
[DataDefinition]
|
||||
public sealed partial class TriggerBehavior : IThresholdBehavior
|
||||
{
|
||||
/// <summary>
|
||||
/// The trigger key to use when triggering.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string? KeyOut { get; set; } = TriggerSystem.DefaultTriggerKey;
|
||||
|
||||
public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
|
||||
{
|
||||
system.TriggerSystem.Trigger(owner, cause);
|
||||
system.TriggerSystem.Trigger(owner, cause, KeyOut);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Server.DeviceLinking.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Shared.DeviceLinking;
|
||||
using Content.Shared.DeviceLinking.Events;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user