Compare commits

...
139 Commits
Author SHA1 Message Date
pre-commit-ci[bot] 8e7895cf57 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2026-07-21 02:14:08 +00:00
Vanessa 162db0b954 yips 2026-07-20 21:08:58 -05:00
Delta-V bot 196419daf0 Automatic changelog update 2026-07-21 02:05:28 +02:00
nlaky ee01a470cf Fix vulp helmet sprites (#6201) 2026-07-21 00:05:08 +00:00
Delta-V bot c0b78a5065 Automatic changelog update 2026-07-21 01:46:30 +02:00
ArionGekkota 3b27cb1630 Pka upstream merge (#6258)
* PKA changes to upstream PKA balance

* Nerfed goliath and basilisk health

* Nerfed carp HP (3 shots to kill with unupgraded PKA)
2026-07-20 18:46:11 -05:00
Delta-V bot fc77ebae4d Automatic changelog update 2026-07-21 01:37:26 +02:00
Proxy also works :3 00d1991154 traitors get 30 tc (#6275)
* traitors get 30 tc

* Update roundstart.yml

* higher is fewer woops

* again

* like this?
2026-07-20 23:37:06 +00:00
William Lemon f20d8d9f7f Toolshed Additions: Field & DoExt commands (#6329)
* Toolshed Additions

* Removed MarkingCommand, added description to FieldCommand

* Added DoExt command
2026-07-20 19:28:39 -04:00
Delta-V bot ae4a864ad0 Automatic changelog update 2026-07-21 01:23:48 +02:00
dbe955ca17 Cargo bounty console improvements (with changes) (#6306)
* simple fix for "Approved by: Self" on all cargo invoices

* port of ruddygreat's bounty console improvements to DeltaV

* modified tooltips and fixed a few importing errors

* StatusLabel in BountyEntry.xaml.cs

* final stupid tweak

* removed unrelated bugfix PR that snuck into this branch somehow

* Cargo bounty fix requests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: cargomouse <dboozlebeep@gmail.com>
Co-authored-by: Jessica Harvey <itsjessagain23@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-20 18:23:28 -05:00
Delta-V bot 19ebd10ad1 Automatic changelog update 2026-07-21 01:18:12 +02:00
pathetic meowmeow dcd0fb693c Evidence bags (#6280)
* Evidence bags

* tests

* fix the gridinv thing
2026-07-20 18:17:52 -05:00
Delta-V bot 9a6cfb2bfb Automatic changelog update 2026-07-21 00:44:20 +02:00
KOTOB 35fa80f737 Kill security poncho (#6332)
* ughhh

* explode

* explode harder
2026-07-20 17:44:01 -05:00
Delta-V bot 3b7304d092 Automatic changelog update 2026-07-21 00:23:18 +02:00
pootslap da7468e79e Fixed improvised shotgun recipe (#6327)
fixed recipes
2026-07-20 17:22:59 -05:00
Delta-V bot 609bf88d9d Automatic changelog update 2026-07-21 00:21:43 +02:00
freezer dog b71e0a2edf vulpkanin yip (#6301)
* ok i think this works? idunno

* now its working

* fixin some namespace stuff thank ya stxcking
2026-07-20 17:21:23 -05:00
Delta-V bot aacfbd17f8 Automatic changelog update 2026-07-21 00:20:31 +02:00
pathetic meowmeow 6fda61e9cb Report global coordinates on the crew monitor (#6326) 2026-07-20 17:20:11 -05:00
Delta-V bot e47ee2601b Automatic changelog update 2026-07-21 00:11:09 +02:00
064fd77a11 Shadekins arrived (#5481)
* Merge pull request #838 from FoxxoTrystan/Shadekin

Shadekin

# Conflicts:
#	Resources/Prototypes/Body/species_base.yml
#	Resources/Prototypes/Entities/Mobs/Customization/Markings/tattoos.yml
#	Resources/Prototypes/Guidebook/species.yml
#	Resources/Prototypes/Species/species_weights.yml

* Merge pull request #868 from FoxxoTrystan/Shadekin-Perf

Shadekin Performence

* Merge pull request #883 from FoxxoTrystan/Shadekin-Patch

Shadekin Patch + Markings

* Merge pull request #947 from RHSvenson/Shadekin_SurvivalBox

Added and implemented emergency boxes for nonbreathers

* Merge pull request #1861 from ilovehans10/shadekin-guidebook-typo-fixes

Shadekin guidebook typo fixes

* Mars -> Marrs (#2381)

<!-- IT'S NOT WIZDENS REPO, IF YOU WANT TO ADD YOUR CHANGES ON ALL
SERVERS, CREATE PR TO WIZDENS REPO -->

<!-- What do you propose to change with your PR? -->
Changes `@ mars` to `@ marr`s for Shadekin.

<!-- What is the reason for adding these changes? Please post links to
Discussions as well as Bug Reports here. Please describe how this will
change the game balance. -->
Parity with emote wheel. Also, `<PLAYERNAME> mars` feels weird.
(...probably because Mars as in the planet.)

<!--
If your PR contains in-game changes you must provide screenshots/videos
of the changes.
-->

<!-- check boxes for faster reviewing of your PR -->

- [X] I do not require assistance to complete the PR.
- [X] Before posting/requesting review of a PR, I have verified that the
changes work.
- [X] I have added screenshots/videos of the changes, or this PR does
not change in-game mechanics.
- [X] I affirm that my changes are licensed under the [Starlight Fork
License](https://github.com/ss14Starlight/space-station-14/blob/Starlight/LICENSE-Starlight.TXT)
and grant permission for use in this repository under its conditions.

**Changelog**
🆑 Fractalflower
- tweak: Changed Mar emote text to `@ marrs`.

* Fix shadekin guidebook resistance info (#2881)

The shadekin guidebook currently overstates the cellular resistance by
10% and vastly underestimates the bloodloss damage.

The guidebook being accurate helps guide player understanding.

<img width="563" height="669" alt="image"
src="https://github.com/user-attachments/assets/bece997a-5aa4-46f5-9b9f-2fe41dc98e97"
/>

- [X] I do not require assistance to complete the PR.
- [X] Before posting/requesting review of a PR, I have verified that the
changes work.
- [X] I have added screenshots/videos of the changes, or this PR does
not change in-game mechanics.
- [X] I affirm that my changes are licensed under the [Starlight Fork
License](https://github.com/ss14Starlight/space-station-14/blob/Starlight/LICENSE-Starlight.TXT)
and grant permission for use in this repository under its conditions.

**Changelog**

🆑 Penguinwizzard
- fix: Turns out that we were issuing wildly incorrect guidebooks on
Shadekin; an updated edition should now be available for crews.

* New Shadekin Disabilities

* Light hurts Shadekin

Shadekin should get more than a mild sunburn in extreme light

* Changes to make it work

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Foam Immunity Readded

* Flash Modifer works now

* Remove DarkLightComponent

* Add missing Locale for Markings from Den

* Fix Issues, Seperate from _DV namespace

* Yaml Linter Fixes

* ARGH

* ARGHv.2

* ARGHv.3

* Nutribatard instead of Baguette

* Exchange Nutribricks with PSB

* Cotton Baguette

* Changing away from BaseOrganic and Respirator Removal in Code

* Fulfill Content Review Requests

* Remove Eye Coloration - Unused

* Remove ShadekinPhase entirely

* Attribution correctly linked

* Review Changes

* done yml links correctly now

* yml format in shadekin effects

* Remove yml file mention and read Internal

* Readd Internals

* _StarLight -> _Starlight

* Port to Nubody and maybe fixing some fuckups

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Shadekin Yaml Errors

* Add missing markings name, add missing base_scale

* Remove Internal Removal in base_species. Make it Component based

* Add missing readonly

* Remove Non Breahter emergency boxes, Shadekin normal box

* DV Comment Fixes

* Untouched File?

* Use FlashMultiplierDurationEvent

* Add missing attribution

* Fixed scream attributions

* Shadekins can now properly succumb. Starlight#4746

---------

Co-authored-by: Matthew Herber <32679887+Happyrobot33@users.noreply.github.com>
Co-authored-by: FoxxoTrystan <45297731+FoxxoTrystan@users.noreply.github.com>
Co-authored-by: Rinary <rinary.super@gmail.com>
Co-authored-by: FoxxoTrystan <trystan.garnierhein@gmail.com>
Co-authored-by: Tess_the_Evil <tessawfresh@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Tobias Berger <toby@tobot.dev>
Co-authored-by: Vanessa <vanessalouwagie@gmail.com>
2026-07-20 22:10:48 +00:00
Delta-V bot 2f5f2fd491 Automatic changelog update 2026-07-21 00:09:16 +02:00
018d65d99b Imp ports - Novice mark and wearable examine (#6118)
* Obvious Examine (#2462)

* Obvious Examine

* Feature creep is real

* Less words and better colors

* even fewer words, please

* Oops sorry yaml

* Refactor entire Obvious Examine system

* whitespace

---------

Co-authored-by: beck <163376292+widgetbeck@users.noreply.github.com>
# Conflicts:
#	Content.Shared/_Impstation/Examine/DetailedInspectComponent.cs
#	Content.Shared/_Impstation/Examine/DetailedInspectSystem.cs
#	Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl
#	Resources/Prototypes/Entities/Clothing/Neck/cloaks.yml
#	Resources/Prototypes/Entities/Clothing/Neck/medals.yml
#	Resources/Prototypes/Entities/Clothing/Neck/pins.yml
#	Resources/Prototypes/Entities/Clothing/Neck/scarfs.yml
#	Resources/Prototypes/_Impstation/Entities/Clothing/Neck/cloaks.yml
#	Resources/Prototypes/_Impstation/Entities/Clothing/Neck/misc.yml
#	Resources/Prototypes/_Impstation/Entities/Clothing/Neck/pins.yml
#	Resources/Prototypes/_Impstation/Entities/Clothing/Neck/scarfs.yml

* Novice's mark (#2626)

* Adding the item

* Update descriptions

* Add to trinket list, add to all trainee roles

* Add to PTech

* License fix

* And credit fix.

 Be nice it's my first sprite implementation lol
# Conflicts:
#	Resources/Prototypes/Catalog/VendingMachines/Inventories/cart.yml
#	Resources/Prototypes/Loadouts/loadout_groups.yml
#	Resources/Prototypes/Roles/Jobs/Engineering/technical_assistant.yml
#	Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml
#	Resources/Prototypes/_DV/Roles/Jobs/Cargo/cargo_assistant.yml
#	Resources/Prototypes/_Impstation/Entities/Clothing/Neck/pins.yml
#	Resources/Prototypes/_Impstation/Loadouts/Miscellaneous/trinkets.yml

* killing things i forgot to oops

* fix + select in loadouts for everyone

---------

Co-authored-by: January Nelson <inelsona@gmail.com>
Co-authored-by: beck <163376292+widgetbeck@users.noreply.github.com>
2026-07-20 17:08:56 -05:00
Delta-V bot ca91333906 Automatic changelog update 2026-07-20 22:29:21 +02:00
VanessaandSir Warock 2b1d0bb364 Locking Probers @ 750 Glimmer + Bigger Prober Explosions over 900 Glimmer (#6292)
* Lock the probers :)

* Added normality to oracle. Up'd max intensity to syndicate bomb levels per CR review.

* Apply suggestions from code review

Co-authored-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

---------

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Co-authored-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>
2026-07-20 22:29:02 +02:00
Delta-V bot a34e8bff90 Automatic changelog update 2026-07-20 22:14:18 +02:00
b67c029061 Port Item Offering from Euphoria (#5597)
* Item offering port (#96)

* Offer item system port

* More fixes

* Make the formatting a bit more readable

* Add a missing keybind

* Add missing alert click handler and make some of the code more readable

* Duplicate offer-item-system.ftl

Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com>

* Namespace fix and prediction fixes

* Port various carrying and pseudo-item fixes from floofstation

* Refactor the offer system to hopefully bring more clarity

* Final fixes

* Final final final fixes maybe

* Sike, just do it the proper way

---------

Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com>

* fixes

* empty commit (weird test fail?)

* Moved some stuff to shared. Reorganized a bit. I could be here all day...

---------

Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com>
Co-authored-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com>
Co-authored-by: Vanessa <vanessalouwagie@gmail.com>
2026-07-20 15:13:57 -05:00
Delta-V bot 72f6bff008 Automatic changelog update 2026-07-20 22:07:19 +02:00
KOTOBandpre-commit-ci[bot] baf36b659d Freighter Crew's Jumpsuit (#6331)
* my larp...

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-20 20:06:59 +00:00
Delta-V bot 0488fcbf8c Automatic changelog update 2026-07-20 19:39:15 +02:00
KOTOBandVanessa edc2b87fa1 Cosmic Censer no longer requires fuel (#5016)
* fun allowed

* guidebook update

* Update Resources/Prototypes/_DV/CosmicCult/Objects/censer.yml

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: KOTOB <59124164+kotobdev@users.noreply.github.com>

* Update Resources/Prototypes/_DV/CosmicCult/Objects/censer.yml

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: KOTOB <59124164+kotobdev@users.noreply.github.com>

---------

Signed-off-by: KOTOB <59124164+kotobdev@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-20 12:38:50 -05:00
Delta-V bot 3885aee7cf Automatic changelog update 2026-07-20 02:25:02 +02:00
ConstantlyConfused 859f0418ac Bring back the IPC "Boop" and "Whirr" emotes for cyborgs (#6310)
* return, buzz, whirr, and maybe boop emotes (for borgs)

* cleanup

* remove buzz, since it seems unused???
2026-07-19 19:24:43 -05:00
Delta-V bot d1385ab95b Automatic changelog update 2026-07-20 02:13:11 +02:00
1e45f2da21 Chef's Kimono (#6341)
* Adds the chef kimono

The drobe thing doesn't work yet

* Adds loadout groups

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Apply suggestion from @ShepardToTheStars

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: BriBrooo <45323530+Bribrooo@users.noreply.github.com>

* Rename ChefJobShoes to ChefShoes in loadouts

Signed-off-by: BriBrooo <45323530+Bribrooo@users.noreply.github.com>

---------

Signed-off-by: BriBrooo <45323530+Bribrooo@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-19 19:12:51 -05:00
Delta-V bot 64c50527c3 Automatic changelog update 2026-07-19 18:38:45 +02:00
Myra d7ef3b4a06 Fix pills not having a taste (#5063) (#6299)
The edible-swallow locale message used by pills was missing the
{$flavors} placeholder that edible-nom, edible-slurp and edible-gulp
all have. IngestionSystem always passes the computed flavor text, so
pills silently dropped it. Eating a pill now shows its taste again,
e.g. "You swallow the pill. Tastes sweet."
2026-07-19 11:38:26 -05:00
Delta-V bot 23ec100ed8 Automatic changelog update 2026-07-19 18:19:49 +02:00
SumofThreePartsandVanessa d62ca61fb4 I halved the chance for the Escape objective, again. (#6323)
* Doing the thing again

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* Apply suggestions from code review

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

---------

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>
Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-19 11:19:30 -05:00
Delta-V bot 229a857b7e Automatic changelog update 2026-07-19 18:19:07 +02:00
dd9c88ca4b Eventing Toolkit - The Great White (#6317)
* Added the Space Dragon Matriarch

* moved the fireball to its own projectile thingy

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update Resources/Prototypes/_DV/Entities/Mobs/Player/dragon.yml

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: einknusprigestoast <90181825+einknusprigestoast@users.noreply.github.com>

* Fixed Parenting (god i wish this was this easy IRL)

* Huh?

* Accidentally deleted something i didnt want to delete

* Upped Blunt regeneration

* Apply suggestion from @ShepardToTheStars

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: einknusprigestoast <90181825+einknusprigestoast@users.noreply.github.com>

* Apply suggestion from @ShepardToTheStars

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

* Apply suggestion from @ShepardToTheStars

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

---------

Signed-off-by: einknusprigestoast <90181825+einknusprigestoast@users.noreply.github.com>
Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-19 11:18:47 -05:00
github-actions[bot]andDeltaV-Bot aaad3b5c00 Update Credits (#6336)
Co-authored-by: DeltaV-Bot <github@deltav.gay>
2026-07-19 04:05:18 +02:00
Delta-V bot addfc247bf Automatic changelog update 2026-07-17 06:40:25 +02:00
6affab00ea Reworked hitman kits (#6270)
* Reworked hitman kits, first draft

* Fixed spacing for the kits

* Update hitman-case.ftl

Rename samurai to ninja kit

* Update hitman_case_catalog.yml

* Update hitman-case.yml

* fixed .ftl error

* Added blue oni mask to ninja kit

* fix hitman_case_catalog.yml, wrong mask ID

* Replaced the high frequency blade with a medium frequency blade - this weapon has a lower reflect chance, and deals heat damage instead of shock.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Small tweak

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Stxcking <217132821+Stxcking@users.noreply.github.com>
2026-07-17 04:40:05 +00:00
Delta-V bot 7f85b2a196 Automatic changelog update 2026-07-17 06:31:43 +02:00
Velitation a7d25c697f Mime fashion (#6307)
* Added 3 new neck items, 1 new coat, 1 new shoe, and 2 new hats to mime loadout

Also added shoe selection to the mime loadout, new coat to the uniform printer, and new coat + boots to the autodrobe.

* Added missing newlines
2026-07-17 00:31:23 -04:00
Delta-V bot 61884f5fe1 Automatic changelog update 2026-07-17 05:51:10 +02:00
ollyoandStxcking ebcd3b23f9 Slime Nubody tweaks and new markings (incl. ports from Impstation) (#6288)
* Slime people tweaks and new markings (incl. ports from Impstation)
-Removed eyes, mouth, nose, and torso bitties from base Slime person sprite
   -Added them back in as optional markings (excl. mouth as Delta-V has lips already)
-Added the new "OrganSlimeEyes" to Slime people to handle eye markings
-Ported Cyclops and Droopy eyes from Impstation
   -Assigned Droopy eyes as "Droopy Eyes (Left)"
   -Made corresponding Droopy eyes on the right side
   -Added "Four eyes" marking
-Removed eyeshadow tattoo markings from Slime people
   -Added a copy into _DV's makeup directory assigned purely to Slime people
   -Made new matching eyeshadows for the various new eye types
-Adjusted the marking limits to make sense with the tweaks
-Moved and reorganized the Slime Elf Ears within the _DV directories to make more sense

* Fixed Slime people full.png sprite dimensions

* -Removed "followSkinColor" from Prototypes\_Impstation\Entities\Mobs\Customization\Markings\slime.yml causing an error

* Update Resources/Prototypes/Body/Species/slime.yml

Co-authored-by: Stxcking <217132821+Stxcking@users.noreply.github.com>
Signed-off-by: ollyo <296974732+ollyoaner@users.noreply.github.com>

* Update Resources/Prototypes/Entities/Mobs/Customization/Markings/tattoos.yml

Co-authored-by: Stxcking <217132821+Stxcking@users.noreply.github.com>
Signed-off-by: ollyo <296974732+ollyoaner@users.noreply.github.com>

* Update Resources/Prototypes/Body/Species/slime.yml

Co-authored-by: Stxcking <217132821+Stxcking@users.noreply.github.com>
Signed-off-by: ollyo <296974732+ollyoaner@users.noreply.github.com>

* - Fixed formatting and improved in line comment readability.
- Moved eyeshadow additions from makeup to Slime categories
- Added "matchskin" to relevant body markings that are meant to follow skin color

* -Returned Eyeshadow to eye markings category
-Returned Slime to whitelisted group in tattoos.yml
-Removed Eye markings limit and the requirement to have eyes
-Added two new eyes to complement the r/l eyes for more eye mixing
-Tweaked inline readability and organization

* Removed outdated prototype MatchSkin from slime.yml

---------

Signed-off-by: ollyo <296974732+ollyoaner@users.noreply.github.com>
Co-authored-by: Stxcking <217132821+Stxcking@users.noreply.github.com>
2026-07-16 23:50:51 -04:00
Delta-V bot 1a23a02b5e Automatic changelog update 2026-07-16 22:24:47 +02:00
RileyandVanessa f6572840b1 Nuclear scientist (#6283)
* Added Nuclear Scientist alt job.

The Nuclear Reactor can be difficult for those to learn and easy for those to blow up.
Put the "experts" on the job.

* Fixed the meta

Meta fixses.

* Apply suggestions from code review

Thanks ShepardToTheStars.
I'm bad at doing these, but getting better.

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: Riley <applesmithworks@gmail.com>

---------

Signed-off-by: Riley <applesmithworks@gmail.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-16 15:24:27 -05:00
Delta-V bot 8680f5c4fd Automatic changelog update 2026-07-15 20:43:48 +02:00
MD360 670b6d0858 Fugi paper fix (#6308)
* +\n

* missed one /n

* missed \n #2
2026-07-15 18:42:51 +00:00
Delta-V bot 94004e3ce0 Automatic changelog update 2026-07-15 03:58:24 +02:00
Vanessa fd09b8f68e Airlock Access Override Removes Access, Give Engineers Access Config (#6263)
* doors access is now broken.

* Access configs for Engi

* AI can see modified accesses now

* Added ability to see access on Engi borgs

* Fixed comment and namespace

* comment

* Also add to Revenant.

* Update Resources/Prototypes/_Mono/Recipes/Lathes/tools.yml

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

---------

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-15 03:58:05 +02:00
Delta-V bot d8edffcbb2 Automatic changelog update 2026-07-15 02:43:39 +02:00
VelitationandStxcking 8316434da2 Revert the upstream changes to the mime PDA (#6252)
* Reverted the upstream changes to the mime PDA

* Comment Change

---------

Co-authored-by: Stxcking <217132821+Stxcking@users.noreply.github.com>
2026-07-15 00:43:19 +00:00
Delta-V bot 6b03d1cc80 Automatic changelog update 2026-07-14 03:38:47 +02:00
Cepelinas1 2f68c7329f Give animals and pests nightvision (#5902)
* first

* fix a lot of things

* i forgot some mobs

* snails

* cooobras
2026-07-14 01:38:27 +00:00
Delta-V bot e8138473d1 Automatic changelog update 2026-07-14 02:30:25 +02:00
Field Command a114cf88d0 Midpoint pool addition! (#6242)
* Midpoint Pool Update

* Whoops, better remember disposals
2026-07-13 17:30:06 -07:00
Delta-V bot ff14cb6846 Automatic changelog update 2026-07-13 23:26:20 +02:00
e639f423f4 Minor Xenoborg Fixes and Tweaks (#6278)
* Disallowed crew IDs and talking over binary for xenoborg borgs.

* Added tag

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add a EMP resistant battery

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* added EMP duration resistance

* Fixed attribution

* Fixed xenoborg magnet bags. Made the core suck up materials.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Removed Xenoborg ID chips since they should never have more than Xenoborg access

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Apply suggestions from code review

Co-authored-by: Radezolid <snappednexus@gmail.com>
Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

* meta.json ordering

---------

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Radezolid <snappednexus@gmail.com>
2026-07-13 18:26:00 -03:00
Delta-V bot 57e5564ff8 Automatic changelog update 2026-07-13 22:37:11 +02:00
Vanessa 48921f9af9 no more animated zombie objects (#6291) 2026-07-13 22:36:52 +02:00
Delta-V bot 8bd44c5e7b Automatic changelog update 2026-07-13 21:58:45 +02:00
Coryn 303e1f4563 Cloning and Paradox Cone height workaround (#6205) 2026-07-13 14:58:25 -05:00
Delta-V bot 8003517bbc Automatic changelog update 2026-07-13 19:38:27 +02:00
Vanessa 6486b49bf3 Fixed derelict borg AA (#6284) 2026-07-13 14:38:08 -03:00
Vanessa aabf5ac1bb Fix syndie meal test failure (#6290) 2026-07-13 13:12:08 -04:00
Delta-V bot b4daabc55f Automatic changelog update 2026-07-13 18:16:39 +02:00
Velitationandpre-commit-ci[bot] 338ac84008 Add 2 new outfits and a mantle for mime (#6264)
* Added 2 new outfits and a mantle for mime

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Comment Addressed

- Removed changes from \Loadouts\loadout_groups.yml
- Made changes to \_DV\Loudouts\loutout_groups.yml

* Addressed Comment (again)

I missed a spot... oops
- Removed changes from \Loadouts\loadout_groups.yml
- Made changes to \_DV\Loadouts\loadout_groups.yml

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Probably shouldn't have made that second commit

My fault

- Undid the previous commit

* Removed duplicate

- Removed the duplicate loadoutGroup for MimeJumpsuit that I added to \_DV\Loadouts\loadout_groups.yml
- Readded the changes to \Loadouts\loadout_groups.yml

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-13 11:16:19 -05:00
Delta-V bot 61e8547327 Automatic changelog update 2026-07-13 16:24:44 +02:00
730cba2ee1 Remove telepads (#6266)
* Kill cargo telepad

* Remove telepad from random spawners & recipes

* Fixed comment conventions

* Update Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

---------

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Co-authored-by: Jessica Harvey <itsjessagain23@gmail.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-13 14:24:24 +00:00
Delta-V bot 6089c30923 Automatic changelog update 2026-07-13 15:51:31 +02:00
ArionGekkotaandpre-commit-ci[bot] 4e6eee4854 Added the small arms mining kit (#6260)
* Added the small arms mining kit

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-13 08:51:12 -05:00
Delta-V bot 71302e037c Automatic changelog update 2026-07-13 15:46:44 +02:00
pootslap fd0a91733f Make improvised/forged weapons and armour uncraftable (#6250)
* remove recipes

thanks radezolid

* forge too
2026-07-13 08:46:24 -05:00
e7c0c98258 Adds Invisible Walls (#6287)
* Wow! Invisible!

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update Resources/Prototypes/_DV/Entities/Structures/Walls/invisible.yml

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: William Lemon <William.Lemon2@gmail.com>

* Apply suggestion from @ShepardToTheStars

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

---------

Signed-off-by: William Lemon <William.Lemon2@gmail.com>
Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-13 13:45:10 +00:00
Delta-V bot df99ef84f5 Automatic changelog update 2026-07-13 15:44:26 +02:00
7932eddb48 SRT Part 4 - The fake balancing strikes back (#6233)
* Added Caustic, Asphyxiation and Radiation regeneration.

* *coughs*

* Added the Eviscerator

* Removed explonades, added Truncheon

* whoops, stole the mateba from the rest of the teams

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* WHY DID IT DO THAT IT WAS NOT SUPPOSED TO DO THAT

* added Tags

* Update Resources/Prototypes/_DV/tags.yml

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: einknusprigestoast <90181825+einknusprigestoast@users.noreply.github.com>

* Update Resources/Prototypes/_DV/tags.yml

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: einknusprigestoast <90181825+einknusprigestoast@users.noreply.github.com>

* Update Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/backpackfed.yml

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: einknusprigestoast <90181825+einknusprigestoast@users.noreply.github.com>

* Update Resources/Prototypes/_DV/Entities/Objects/Weapons/Guns/backpackfed.yml

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: einknusprigestoast <90181825+einknusprigestoast@users.noreply.github.com>

* Update Resources/Prototypes/_DV/Entities/Clothing/Back/specific.yml

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: einknusprigestoast <90181825+einknusprigestoast@users.noreply.github.com>

* Update Resources/Prototypes/_DV/Entities/Clothing/Back/specific.yml

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: einknusprigestoast <90181825+einknusprigestoast@users.noreply.github.com>

---------

Signed-off-by: einknusprigestoast <90181825+einknusprigestoast@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-13 08:44:06 -05:00
Delta-V bot 72efa8c9d3 Automatic changelog update 2026-07-13 15:32:24 +02:00
Coryn cdc8aeb3a6 Avali feather colors are correct again (#6285) 2026-07-13 08:32:04 -05:00
Delta-V bot 9e047522e9 Automatic changelog update 2026-07-13 15:16:46 +02:00
Field Command 2e7134f028 Xenoborgs have turrets now! (#6244)
Xenoborgs have turrets now
2026-07-13 08:16:25 -05:00
github-actions[bot]andDeltaV-Bot 8d772a67fa Update Credits (#6281)
Co-authored-by: DeltaV-Bot <github@deltav.gay>
2026-07-12 04:07:22 +02:00
TNE 310a2c6575 Add Meridian server config preset (#6277) 2026-07-11 23:47:08 +02:00
VelcroboyandVelcroboy 7b6a41b28f Map Edits: The Hive (#6107)
Co-authored-by: Velcroboy <velcroboy333@hotmail.com>
2026-07-11 13:04:53 -07:00
Delta-V bot 5ddec75e0b Automatic changelog update 2026-07-11 19:25:26 +02:00
3f29960640 PORT: Imp Learner pai (#5924)
* learner pais!  (#2269)

* almost published to master holy fuck

* vomits

* grhg

* mqole guiding light

* yupdate!

* escaped the torment nexus of losing my head

---------

Co-authored-by: mousesweater <moondogg228@gmail.com>

* fix where the sprites are

* learner pais!  (#2269)

* almost published to master holy fuck

* vomits

* grhg

* mqole guiding light

* yupdate!

* escaped the torment nexus of losing my head

---------

Co-authored-by: mousesweater <moondogg228@gmail.com>

* fix where the sprites are

* Adds a golden personal AI variant as a trinket, requiring 10hrs Silicon playtime

* Revert "Adds a golden personal AI variant as a trinket, requiring 10hrs Silicon playtime"

This reverts commit 4f545547ed.

* remove golden pai fix names

* move the imp item to the deltaV table (?)

* merge conflict ops

---------

Signed-off-by: Theo <rebe83a@gmail.com>
Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Co-authored-by: mousesweater <55769023+Mousetrinity@users.noreply.github.com>
Co-authored-by: mousesweater <moondogg228@gmail.com>
Co-authored-by: AftrLite <61218133+AftrLite@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-11 17:25:07 +00:00
Delta-V bot fe940f0289 Automatic changelog update 2026-07-11 18:35:16 +02:00
70c0494061 Remove ion damage (#5960)
* comment out borg ion damage

* remove ion damage from disabler

* actually nuke it

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Additional removals.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Vanessa <vanessalouwagie@gmail.com>
2026-07-11 16:34:56 +00:00
Delta-V bot 4b0b6ff16e Automatic changelog update 2026-07-11 18:30:27 +02:00
ollyoandpre-commit-ci[bot] e4826f3b8a Elf ears for Slime People (#6265)
* Added long ears markings to Slime people.
    -Ported and edited human long ear marking sprites to match Slime palette.
    -Placed Slime long ears in (HeadSide) marking slot
    -Placed a limit marking of 1 on HeadSide for Slime

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-11 16:30:07 +00:00
Delta-V bot a8796530e6 Automatic changelog update 2026-07-11 18:09:42 +02:00
Radezolid 1afb572366 Add a nanite applicator to the engie toolbelt (#6261)
* Added tools

* Kill the gas analyzer
2026-07-11 11:09:22 -05:00
Delta-V bot 08e4ee47c3 Automatic changelog update 2026-07-11 10:29:39 +02:00
Radezolid 097f165961 Re-add the knuckleduster to the LO's locker. (#6243)
Reverted
2026-07-11 10:29:19 +02:00
Delta-V bot a8cd6be09c Automatic changelog update 2026-07-10 22:22:01 +02:00
ArionGekkota 3698acd6d2 Allow allulalo to fit in bags (#6248)
* Allow allulalo to fit in bags

* Added delta-v comment
2026-07-10 22:21:41 +02:00
Delta-V bot b35b68b8aa Automatic changelog update 2026-07-10 22:20:28 +02:00
f585bcd233 toolbelt add multitool and welding mask because really it should have those (#6217)
* toolbelt add multitool and mask

* Update Resources/Prototypes/Catalog/Fills/Items/belt.yml

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>

---------

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Co-authored-by: stormyatt <stormyatt@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-10 20:20:08 +00:00
Delta-V bot e2f79f2236 Automatic changelog update 2026-07-10 22:08:52 +02:00
CheddaCheez f4c6352dea Rodentia Ears + Whiskers (#6273)
Move marking and up limit

Whiskers moved from HeadTop to HeadSide.
HeadSide marking limit upped from 1 to 2.
2026-07-10 22:08:32 +02:00
Delta-V bot 54514adf64 Automatic changelog update 2026-07-10 21:58:37 +02:00
Vanessaandpre-commit-ci[bot] 75d30a857a Sometimes, dead is better. (DAGD On Death Implanters) (#6221)
* Added unrevivable implanter for DAGD

* Verbage

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Choose your own adventure

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* local and admin menu fixes

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-10 21:58:17 +02:00
Vanessa 519ca118c4 Merge pull request #6228 from DeltaV-Station/zombie-survival-fix
Fix Convert to Survival Behavior during Zombies
2026-07-10 14:17:30 -05:00
Delta-V bot ca1f82d430 Automatic changelog update 2026-07-10 19:22:57 +02:00
Vanessa d62a4911e7 MedHUDs no longer show your own health bar :) (#6241)
Im evil
2026-07-10 19:22:38 +02:00
Vanessa 2984ecbb8c Undo a change 2026-07-10 11:54:02 -05:00
Vanessa 304c99dc2e Removed a comment 2026-07-10 11:48:31 -05:00
Vanessa 8030fe1b2a Silly linq queries 2026-07-10 11:47:48 -05:00
Vanessa 795772ecc2 Switched up checks 2026-07-10 10:06:00 -05:00
Delta-V bot 37327a2c70 Automatic changelog update 2026-07-10 17:03:32 +02:00
Vanessa f3361860d2 Fix Tech Disk Test Failures (#6271) 2026-07-10 11:03:12 -04:00
Delta-V bot 86a9eff122 Automatic changelog update 2026-07-10 16:05:37 +02:00
Radezolid 2ff9e1d56a Raise the point price of seismic charges (#6245)
up goes the price
2026-07-10 09:05:17 -05:00
Delta-V bot 48f1cff536 Automatic changelog update 2026-07-10 15:59:49 +02:00
Carol a86501907f Add locked storage component to secure cabinets (#6269)
added LockedStorage component to secure cabinets
2026-07-10 08:59:29 -05:00
Delta-V bot 4bdcb0d556 Automatic changelog update 2026-07-09 20:03:39 +02:00
1351e0fb67 Rewrite of C3 introduction of C3.1-C3.3 (#5929)
* boop

* Update Resources/ServerInfo/Guidebook/_DV/Rules/RoleRules/C3_Antags.xml

Co-authored-by: This_Is_Gray <167829864+IAmNotGray@users.noreply.github.com>
Signed-off-by: Halo3moth <mdavid.wininger@gmail.com>

* Update Resources/ServerInfo/Guidebook/_DV/Rules/RoleRules/C3_Antags.xml

Co-authored-by: This_Is_Gray <167829864+IAmNotGray@users.noreply.github.com>
Signed-off-by: Halo3moth <mdavid.wininger@gmail.com>

* Update Resources/ServerInfo/Guidebook/_DV/Rules/RoleRules/C3_Antags.xml

Co-authored-by: BarryNorfolk <barrynorfolkman@protonmail.com>
Signed-off-by: Halo3moth <mdavid.wininger@gmail.com>

* Update Resources/ServerInfo/Guidebook/_DV/Rules/RoleRules/C3_Antags.xml

Co-authored-by: This_Is_Gray <167829864+IAmNotGray@users.noreply.github.com>
Signed-off-by: Halo3moth <mdavid.wininger@gmail.com>

---------

Signed-off-by: Halo3moth <mdavid.wininger@gmail.com>
Co-authored-by: This_Is_Gray <167829864+IAmNotGray@users.noreply.github.com>
Co-authored-by: BarryNorfolk <barrynorfolkman@protonmail.com>
2026-07-09 13:03:19 -05:00
Delta-V bot f8e59733dd Automatic changelog update 2026-07-09 15:29:26 +02:00
ConstantlyConfused 4750e885b2 Add missing Space Law Sections to the guidebook (#6223)
* move spacelaw into space law folder

* move procedural defense to its own file

* add sentences and modifers to SpaceLaw guidebook
2026-07-09 08:29:06 -05:00
Delta-V bot a7d34aacda Automatic changelog update 2026-07-09 13:39:08 +02:00
TheoandVanessa 91494215ca ghost buffers tweaks (#5981)
* tweaks

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

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: Theo <tad3@illinois.edu>

---------

Signed-off-by: Theo <tad3@illinois.edu>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-09 11:38:48 +00:00
ConstantlyConfused 5e50b6969c Fix the Umbroxol Description (#6247)
fix  the umbrox description
2026-07-09 06:25:03 -05:00
einknusprigestoast 4538b4ded1 Added Caustic, Asphyxiation and Radiation regeneration to the combat nanites. (#6231)
* Added Caustic, Asphyxiation and Radiation regeneration.

* *coughs*
2026-07-09 06:24:21 -05:00
Delta-V bot cdbf170b37 Automatic changelog update 2026-07-09 06:43:03 +02:00
freezer dog daf03f45ed bigger magnum boxes (and they fit in bandoliers now) (#6226)
* doubled magnum box capacity, whitelist for bandoliers holdin magnum cartridges, and fixed 2 misspellings (cause i mighta caused one of em oops)

* dumbass dog is stupid who woulda thunk it....
2026-07-08 23:42:43 -05:00
Delta-V bot 987678965f Automatic changelog update 2026-07-09 05:54:14 +02:00
Theo 663952f2fb Sabotage borg nerf (#6080)
* modules changed

* 1 tc change lol
2026-07-08 22:53:55 -05:00
Delta-V bot 46a37b1caf Automatic changelog update 2026-07-09 03:25:05 +02:00
jessiscah23andJessica Harvey bcc50db33b Fix salvage magnet asteroids not spawning in ore. (#5973)
Co-authored-by: Jessica Harvey <itsjessagain23@gmail.com>
2026-07-09 01:24:45 +00:00
Apersos-collandVanessa 30cfa646e4 Grav Gauntlet weapon changes and resprite (#5951)
* medium overhaul to weapon and sprite
removed taser
added Reflection (base 30% chance)
added speed up while in hand (25% speed up)
changed icon to fit more with artstyle plus bluesec
inhand sprites match new sprite

* OBSENLY SMALL CHANGED (small fixes to icon color and suitStorage being 1 to far up

* added clothing slowdown resist
added passive block modifier (makes it act like a shield)

* added/removed to fit with changes asked.
removed blocking
added prying
added higher damage

* fixing new sprite

* Update Hos-Briefcase.ftl

forgot to update discription

Signed-off-by: Apersos-coll <collsherlo@gmail.com>

* fixing new sprite

* fixing

* more fixing

* attempting to see if that was a false positive (fixing stuff)

i changed a word slightly to see if it was false positive cause i checked the log and there was no such mention of my weapon at all 
anyways i just changed a single word so if it works this time i dont have to make a second commit

Signed-off-by: Apersos-coll <collsherlo@gmail.com>

---------

Signed-off-by: Apersos-coll <collsherlo@gmail.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-07-08 19:54:32 -05:00
ConstantlyConfused 91ff29416b Merge pull request #6251 from Eternally-Confused/blows-up-IPC
Remove another mention of IPCs
2026-07-08 17:07:28 -05:00
Vanessa 74d687ee4e Check if there are any pending zombies 2026-07-05 23:02:36 -05:00
Vanessa eef2b2215d whitespace 2026-07-05 22:41:46 -05:00
Vanessa b74569d20b Check II un-turned count. 2026-07-05 22:38:20 -05:00
600 changed files with 21296 additions and 2934 deletions
@@ -2,6 +2,7 @@ using Content.Client.Cargo.UI;
using Content.Shared.Cargo.Components;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
using Content.Shared._DV.Cargo.Components; // DeltaV: Bounty claim messages
namespace Content.Client.Cargo.BUI;
@@ -30,6 +31,18 @@ public sealed class CargoBountyConsoleBoundUserInterface : BoundUserInterface
{
SendMessage(new BountySkipMessage(id));
};
// DeltaV: bounty claim stuff begins
_menu.OnClaimButtonPressed += id =>
{
SendMessage(new BountyClaimedMessage(id));
};
_menu.OnStatusOptionSelected += (id, status) =>
{
SendMessage(new BountySetStatusMessage(id, status));
};
// DeltaV: bounty claim stuff ends
}
protected override void UpdateState(BoundUserInterfaceState message)
+14 -4
View File
@@ -10,6 +10,8 @@
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
<RichTextLabel Name="RewardLabel"/>
<RichTextLabel Name="ManifestLabel"/>
<RichTextLabel Name="ClaimedBylabel"/> <!-- DeltaV bounty claim -->
<RichTextLabel Name="StatusLabel"/> <!-- DeltaV bounty claim -->
</BoxContainer>
<Control MinWidth="10"/>
<BoxContainer Orientation="Vertical" MinWidth="120">
@@ -17,14 +19,22 @@
<Button Name="PrintButton"
Text="{Loc 'bounty-console-label-button-text'}"
HorizontalExpand="False"
HorizontalAlignment="Right"
StyleClasses="OpenRight"/>
StyleClasses="OpenBoth"/>
<Button Name="SkipButton"
Text="{Loc 'bounty-console-skip-button-text'}"
HorizontalExpand="False"
HorizontalAlignment="Right"
HorizontalExpand="True"
StyleClasses="OpenLeft"/>
</BoxContainer>
<BoxContainer Orientation="Horizontal" MinWidth="120"> <!-- Begin DeltaV bounty claim content -->
<Button Name="ClaimButton"
Text= "{Loc 'bounty-console-claim-button-text'}"
HorizontalExpand="False"
StyleClasses="OpenRight"/>
<OptionButton Name="BountyStatusSelector"
Access="Public"
StyleClasses="OpenBoth"
HorizontalExpand="True"/>
</BoxContainer> <!-- End DeltaV content-->
<RichTextLabel Name="IdLabel" HorizontalAlignment="Right" Margin="0 0 5 0"/>
</BoxContainer>
</BoxContainer>
@@ -17,6 +17,8 @@ public sealed partial class BountyEntry : BoxContainer
public Action? OnLabelButtonPressed;
public Action? OnSkipButtonPressed;
public Action? OnClaimButtonPressed; // DeltaV
public Action? OnStatusOptionSelected; // DeltaV
public TimeSpan EndTime;
public TimeSpan UntilNextSkip;
@@ -45,6 +47,20 @@ public sealed partial class BountyEntry : BoxContainer
PrintButton.OnPressed += _ => OnLabelButtonPressed?.Invoke();
SkipButton.OnPressed += _ => OnSkipButtonPressed?.Invoke();
// Begin DeltaV bounty claiming
ClaimButton.OnPressed += _ => OnClaimButtonPressed?.Invoke();
BountyStatusSelector.AddItem(Loc.GetString($"bounty-console-status-{nameof(CargoBountyStatus.Undelivered)}"), 0);
BountyStatusSelector.AddItem(Loc.GetString($"bounty-console-status-{nameof(CargoBountyStatus.Waiting)}"), 1);
BountyStatusSelector.AddItem(Loc.GetString($"bounty-console-status-{nameof(CargoBountyStatus.OnShuttle)}"), 2);
BountyStatusSelector.Select((int) bounty.Status);
BountyStatusSelector.ToolTip = Loc.GetString($"bounty-console-status-tooltip-{bounty.Status.ToString()}");
var claimedByText = string.IsNullOrEmpty(bounty.ClaimedBy) ? Loc.GetString("bounty-console-claimed-by-none") : bounty.ClaimedBy;
ClaimedBylabel.SetMarkup(Loc.GetString("bounty-console-claimed-by", ("claimant", claimedByText)));
StatusLabel.SetMarkup(Loc.GetString($"bounty-console-formatted-status-{bounty.Status.ToString()}"));
// End DeltaV bounty claiming
}
private void UpdateSkipButton(float deltaSeconds)
+3 -2
View File
@@ -1,8 +1,9 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
<!--DeltaV - SetSize was 550, now 750 to accomodate bounty claim UI -->
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'bounty-console-menu-title'}"
SetSize="550 420"
SetSize="750 420"
MinSize="400 350">
<BoxContainer Orientation="Vertical"
VerticalExpand="True"
@@ -11,6 +11,8 @@ public sealed partial class CargoBountyMenu : FancyWindow
{
public Action<string>? OnLabelButtonPressed;
public Action<string>? OnSkipButtonPressed;
public Action<string>? OnClaimButtonPressed; // DeltaV
public Action<string, int>? OnStatusOptionSelected; // DeltaV
public CargoBountyMenu()
{
@@ -31,6 +33,8 @@ public sealed partial class CargoBountyMenu : FancyWindow
var entry = new BountyEntry(b, untilNextSkip);
entry.OnLabelButtonPressed += () => OnLabelButtonPressed?.Invoke(b.Id);
entry.OnSkipButtonPressed += () => OnSkipButtonPressed?.Invoke(b.Id);
entry.OnClaimButtonPressed += () => OnClaimButtonPressed?.Invoke(b.Id); // DeltaV
entry.BountyStatusSelector.OnItemSelected += args => OnStatusOptionSelected?.Invoke(b.Id, args.Id); // DeltaV
BountyEntriesContainer.AddChild(entry);
}
+3
View File
@@ -34,6 +34,9 @@ namespace Content.Client.Input
common.AddFunction(ContentKeyFunctions.RotateStoredItem);
common.AddFunction(ContentKeyFunctions.SaveItemLocation);
common.AddFunction(ContentKeyFunctions.Point);
// Floofstation section
common.AddFunction(ContentKeyFunctions.OfferItem);
// Floofstation section end
common.AddFunction(ContentKeyFunctions.ZoomOut);
common.AddFunction(ContentKeyFunctions.ZoomIn);
common.AddFunction(ContentKeyFunctions.ResetZoom);
@@ -75,9 +75,11 @@ public sealed partial class CrewMonitoringNavMapControl : NavMapControl
if (!LocalizedNames.TryGetValue(netEntity, out var name))
name = Loc.GetString("navmap-unknown-entity");
var pos = _xform.ToMapCoordinates(blip.Coordinates); // DeltaV - map-coordinates
var message = name + "\n" + Loc.GetString("navmap-location",
("x", MathF.Round(blip.Coordinates.X)),
("y", MathF.Round(blip.Coordinates.Y)));
("x", MathF.Round(pos.X)), // DeltaV - map-coordinates
("y", MathF.Round(pos.Y))); // DeltaV - map-coordinates
_trackedEntityLabel.Text = message;
_trackedEntityPanel.Visible = true;
@@ -208,6 +208,7 @@ namespace Content.Client.Options.UI.Tabs
AddButton(ContentKeyFunctions.MovePulledObject);
AddButton(ContentKeyFunctions.ReleasePulledObject);
AddButton(ContentKeyFunctions.Point);
AddButton(ContentKeyFunctions.OfferItem); // Floofstation
AddButton(ContentKeyFunctions.RotateObjectClockwise);
AddButton(ContentKeyFunctions.RotateObjectCounterclockwise);
AddButton(ContentKeyFunctions.FlipObject);
@@ -11,6 +11,7 @@ using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player; // DeltaV
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using static Robust.Shared.Maths.Color;
@@ -22,6 +23,7 @@ namespace Content.Client.Overlays;
/// </summary>
public sealed class EntityHealthBarOverlay : Overlay
{
[Dependency] private readonly IPlayerManager _player = default!; // DeltaV
private readonly IEntityManager _entManager;
private readonly IPrototypeManager _prototype;
@@ -40,6 +42,8 @@ public sealed class EntityHealthBarOverlay : Overlay
public EntityHealthBarOverlay(IEntityManager entManager, IPrototypeManager prototype)
{
IoCManager.InjectDependencies(this); // DeltaV
_entManager = entManager;
_prototype = prototype;
_transform = _entManager.System<SharedTransformSystem>();
@@ -69,6 +73,11 @@ public sealed class EntityHealthBarOverlay : Overlay
out var damageableComponent,
out var spriteComponent))
{
// BEGIN DeltaV - You can't see your own bar :godo:
if (_player.LocalEntity is { } player && player.Id == uid.Id)
continue;
// END DeltaV
if (statusIcon != null && !_statusIconSystem.IsVisible((uid, _entManager.GetComponent<MetaDataComponent>(uid)), statusIcon))
continue;
@@ -85,41 +85,40 @@ public sealed class SalvageMagnetBoundUserInterface : BoundUserInterface
{
case AsteroidOffering asteroid:
option.Title = Loc.GetString($"dungeon-config-proto-{asteroid.Id}");
break; // DeltaV: Skip ores since they aren't used with custom generation
// var layerKeys = asteroid.MarkerLayers.Keys.ToList();
// layerKeys.Sort();
//
// foreach (var resource in layerKeys)
// {
// var count = asteroid.MarkerLayers[resource];
//
// var container = new BoxContainer
// {
// Orientation = BoxContainer.LayoutOrientation.Horizontal,
// HorizontalExpand = true,
// };
//
// var resourceLabel = new Label
// {
// Text = Loc.GetString("salvage-magnet-resources",
// ("resource", resource)),
// HorizontalAlignment = Control.HAlignment.Left,
// };
//
// var countLabel = new Label
// {
// Text = Loc.GetString("salvage-magnet-resources-count", ("count", count)),
// HorizontalAlignment = Control.HAlignment.Right,
// HorizontalExpand = true,
// };
//
// container.AddChild(resourceLabel);
// container.AddChild(countLabel);
//
// option.AddContent(container);
// }
//
// break;
var layerKeys = asteroid.MarkerLayers.Keys.ToList();
layerKeys.Sort();
foreach (var resource in layerKeys)
{
var count = asteroid.MarkerLayers[resource];
var container = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
HorizontalExpand = true,
};
var resourceLabel = new Label
{
Text = Loc.GetString("salvage-magnet-resources",
("resource", resource)),
HorizontalAlignment = Control.HAlignment.Left,
};
var countLabel = new Label
{
Text = Loc.GetString("salvage-magnet-resources-count", ("count", count)),
HorizontalAlignment = Control.HAlignment.Right,
HorizontalExpand = true,
};
container.AddChild(resourceLabel);
container.AddChild(countLabel);
option.AddContent(container);
}
break;
case DebrisOffering debris:
option.Title = Loc.GetString($"salvage-magnet-debris-{debris.Id}");
break;
@@ -0,0 +1,73 @@
using System.Linq;
using Content.Shared._DV.Forensics;
using Robust.Client.GameObjects;
using Robust.Client.ResourceManagement;
using Robust.Shared.Containers;
using Robust.Shared.Utility;
namespace Content.Client._DV.Forensics;
public sealed class DVItemSlotVisualsSystem : EntitySystem
{
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;
private static readonly ResPath TextureRoot = new("/Textures");
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVItemSlotVisualsComponent, EntInsertedIntoContainerMessage>(OnInsertedIntoContainer);
SubscribeLocalEvent<DVItemSlotVisualsComponent, EntRemovedFromContainerMessage>(OnRemovedFromContainer);
}
private void RefreshVisuals(Entity<DVItemSlotVisualsComponent> ent)
{
var slot = _container.EnsureContainer<ContainerSlot>(ent, ent.Comp.ItemSlot);
if (slot.ContainedEntity is { } contained)
{
_sprite.CopySprite(contained, ent.Owner);
_sprite.AddLayer(ent.Owner, ent.Comp.FilledSprite);
}
else
{
var sprite = Comp<SpriteComponent>(ent);
var count = sprite.AllLayers.Count();
for (var i = count - 1; i >= 0; i--)
{
_sprite.RemoveLayer((ent, sprite), i);
}
if (ent.Comp.UnfilledSprite is not SpriteSpecifier.Rsi rsi)
{
throw new InvalidOperationException($"{ToPrettyString(ent)} has an unfilled sprite that's not an RSI");
}
if (!_resourceCache.TryGetResource<RSIResource>(TextureRoot / rsi.RsiPath, out var res))
{
throw new InvalidOperationException($"{ToPrettyString(ent)} has invalid RSI: {TextureRoot / rsi.RsiPath}");
}
_sprite.SetBaseRsi(ent.Owner, res.RSI);
_sprite.AddLayer(ent.Owner, ent.Comp.UnfilledSprite);
}
}
private void OnInsertedIntoContainer(Entity<DVItemSlotVisualsComponent> ent, ref EntInsertedIntoContainerMessage args)
{
if (args.Container.ID != ent.Comp.ItemSlot)
return;
RefreshVisuals(ent);
}
private void OnRemovedFromContainer(Entity<DVItemSlotVisualsComponent> ent, ref EntRemovedFromContainerMessage args)
{
if (args.Container.ID != ent.Comp.ItemSlot)
return;
RefreshVisuals(ent);
}
}
@@ -1,5 +0,0 @@
using Content.Shared._DV.Silicons;
namespace Content.Client._DV.Silicons;
public sealed class SiliconEmpSystem : SharedSiliconEmpSystem;
@@ -0,0 +1,71 @@
using System.Numerics;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.UserInterface;
using Robust.Shared.Enums;
using Robust.Shared.Utility;
namespace Content.Client._Floof.OfferItem;
public sealed class OfferItemIndicatorsOverlay : Overlay
{
private readonly IInputManager _inputManager;
private readonly IEntityManager _entMan;
private readonly IEyeManager _eye;
private readonly OfferItemSystem _offer;
private readonly Texture _sight;
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
private readonly Color _mainColor = Color.White.WithAlpha(0.3f);
private readonly Color _strokeColor = Color.Black.WithAlpha(0.5f);
private readonly float _scale = 0.6f; // 1 is a little big
public OfferItemIndicatorsOverlay(IInputManager input, IEntityManager entMan,
IEyeManager eye, OfferItemSystem offerSys)
{
_inputManager = input;
_entMan = entMan;
_eye = eye;
_offer = offerSys;
var spriteSys = _entMan.EntitySysManager.GetEntitySystem<SpriteSystem>();
_sight = spriteSys.Frame0(new SpriteSpecifier.Rsi(new("/Textures/_Floof/Interface/Misc/give_item.rsi"), "give_item"));
}
protected override bool BeforeDraw(in OverlayDrawArgs args)
{
if (!_offer.IsInOfferMode())
return false;
return base.BeforeDraw(in args);
}
protected override void Draw(in OverlayDrawArgs args)
{
var mouseScreenPosition = _inputManager.MouseScreenPosition;
var mousePosMap = _eye.PixelToMap(mouseScreenPosition);
if (mousePosMap.MapId != args.MapId)
return;
var mousePos = mouseScreenPosition.Position;
var uiScale = (args.ViewportControl as Control)?.UIScale ?? 1f;
var limitedScale = uiScale > 1.25f ? 1.25f : uiScale;
DrawSight(_sight, args.ScreenHandle, mousePos, limitedScale * _scale);
}
private void DrawSight(Texture sight, DrawingHandleScreen screen, Vector2 centerPos, float scale)
{
var sightSize = sight.Size * scale;
var expandedSize = sightSize + new Vector2(7f, 7f);
screen.DrawTextureRect(sight,
UIBox2.FromDimensions(centerPos - sightSize * 0.5f, sightSize), _strokeColor);
screen.DrawTextureRect(sight,
UIBox2.FromDimensions(centerPos - expandedSize * 0.5f, expandedSize), _mainColor);
}
}
@@ -0,0 +1,39 @@
using Content.Shared._Floof.OfferItem;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.Player;
namespace Content.Client._Floof.OfferItem;
public sealed class OfferItemSystem : SharedOfferItemSystem
{
[Dependency] private readonly IOverlayManager _overlayManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IInputManager _inputManager = default!;
[Dependency] private readonly IEyeManager _eye = default!;
public override void Initialize()
{
base.Initialize();
_overlayManager.AddOverlay(new OfferItemIndicatorsOverlay(
_inputManager,
EntityManager,
_eye,
this));
}
public override void Shutdown()
{
_overlayManager.RemoveOverlay<OfferItemIndicatorsOverlay>();
base.Shutdown();
}
public bool IsInOfferMode()
{
var entity = _playerManager.LocalEntity;
if (entity == null)
return false;
return IsInOfferMode(entity.Value);
}
}
@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.Access.Systems; // DeltaV
using Content.Server.Cargo.Components;
using Content.Server.NameIdentifier;
using Content.Shared.Access.Components;
@@ -20,6 +21,7 @@ using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Content.Shared._DV.Cargo.Components; // DeltaV: Bounty claim messages
namespace Content.Server.Cargo.Systems;
@@ -28,6 +30,7 @@ public sealed partial class CargoSystem
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly NameIdentifierSystem _nameIdentifier = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelistSys = default!;
[Dependency] private readonly IdCardSystem _idCard = default!; // DeltaV
private static readonly ProtoId<NameIdentifierGroupPrototype> BountyNameIdentifierGroup = "Bounty";
@@ -40,6 +43,8 @@ public sealed partial class CargoSystem
SubscribeLocalEvent<CargoBountyConsoleComponent, BoundUIOpenedEvent>(OnBountyConsoleOpened);
SubscribeLocalEvent<CargoBountyConsoleComponent, BountyPrintLabelMessage>(OnPrintLabelMessage);
SubscribeLocalEvent<CargoBountyConsoleComponent, BountySkipMessage>(OnSkipBountyMessage);
SubscribeLocalEvent<CargoBountyConsoleComponent, BountyClaimedMessage>(OnBountyClaimedMessage); // DeltaV
SubscribeLocalEvent<CargoBountyConsoleComponent, BountySetStatusMessage>(OnSetBountyStatusMessage); // DeltaV
SubscribeLocalEvent<CargoBountyLabelComponent, PriceCalculationEvent>(OnGetBountyPrice);
SubscribeLocalEvent<EntitySoldEvent>(OnSold);
SubscribeLocalEvent<StationCargoBountyDatabaseComponent, MapInitEvent>(OnMapInit);
@@ -111,6 +116,72 @@ public sealed partial class CargoSystem
_audio.PlayPvs(component.SkipSound, uid);
}
// Begin DeltaV bounty claim system
private void OnSetBountyStatusMessage(Entity<CargoBountyConsoleComponent> ent, ref BountySetStatusMessage args)
{
if (_station.GetOwningStation(ent.Owner) is not { } station || !TryComp<StationCargoBountyDatabaseComponent>(station, out var bountyDbComp))
return;
for (var i = 0; i < bountyDbComp.Bounties.Count; i++)
{
var bounty = bountyDbComp.Bounties[i];
if (bounty.Id != args.BountyId)
continue;
var newData = new CargoBountyData
{
Id = bounty.Id,
Bounty = bounty.Bounty,
ClaimedBy = bounty.ClaimedBy,
Status = (CargoBountyStatus)args.Status,
};
bountyDbComp.Bounties[i] = newData;
}
var untilNextSkip = bountyDbComp.NextSkipTime - Timing.CurTime;
_uiSystem.SetUiState(ent.Owner, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(bountyDbComp.Bounties, bountyDbComp.History, untilNextSkip));
}
private void OnBountyClaimedMessage(Entity<CargoBountyConsoleComponent> ent, ref BountyClaimedMessage args)
{
if (_station.GetOwningStation(ent.Owner) is not { } station || !TryComp<StationCargoBountyDatabaseComponent>(station, out var bountyDbComp))
return;
for (var i = 0; i < bountyDbComp.Bounties.Count; i++)
{
var bounty = bountyDbComp.Bounties[i];
if (bounty.Id != args.BountyId)
continue;
string name;
if (_idCard.TryFindIdCard(args.Actor, out var idCard) && idCard.Comp.FullName != null)
{
name = idCard.Comp.FullName;
}
else
{
name = Loc.GetString("bounty-console-claimed-by-unknown");
}
var newData = new CargoBountyData
{
Id = bounty.Id,
Bounty = bounty.Bounty,
ClaimedBy = name.Equals(bounty.ClaimedBy) ? string.Empty : name,
Status = bounty.Status,
};
bountyDbComp.Bounties[i] = newData;
}
var untilNextSkip = bountyDbComp.NextSkipTime - Timing.CurTime;
_uiSystem.SetUiState(ent.Owner, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(bountyDbComp.Bounties, bountyDbComp.History, untilNextSkip));
}
// End DeltaV bounty claim system
public void SetupBountyLabel(EntityUid uid, EntityUid stationId, CargoBountyData bounty, PaperComponent? paper = null, CargoBountyLabelComponent? label = null)
{
if (!Resolve(uid, ref paper, ref label) || !_protoMan.Resolve<CargoBountyPrototype>(bounty.Bounty, out var prototype))
-1
View File
@@ -1,5 +1,4 @@
using Content.Server.Explosion.EntitySystems;
using Content.Shared.Damage; // DeltaV - EMP damage
using Content.Server.Power.EntitySystems;
using Content.Server.Radio;
using Content.Server.SurveillanceCamera;
@@ -23,6 +23,7 @@ using Robust.Shared.Timing;
using System.Linq;
using Content.Shared.EntityEffects.Effects.Solution;
using TimedDespawnComponent = Robust.Shared.Spawners.TimedDespawnComponent;
using Content.Server.Body.Components; // Delta V
namespace Content.Server.Fluids.EntitySystems;
@@ -267,7 +268,8 @@ public sealed class SmokeSystem : EntitySystem
if (!_solutionContainerSystem.ResolveSolution(entity, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution) || bloodSolution.AvailableVolume <= 0)
return;
var blockIngestion = _internals.AreInternalsWorking(entity);
var blockIngestion = _internals.AreInternalsWorking(entity)
|| !HasComp<RespiratorComponent>(entity); // Starlight - Shadekin does not breathe and "AreInternalsWorking" does not check for that
var cloneSolution = solution.Clone();
var availableTransfer = FixedPoint2.Min(cloneSolution.Volume, component.TransferRate);
@@ -18,6 +18,7 @@ using Content.Shared.Zombies;
using Robust.Shared.Player;
using Robust.Shared.Timing;
using System.Globalization;
using System.Linq; // DeltaV
namespace Content.Server.GameTicking.Rules;
@@ -126,15 +127,21 @@ public sealed class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponent>
// BEGIN DeltaV - Change mode to survival if zombies die
var infectedPercent = GetInfectedFraction(false);
if (Math.Round(infectedPercent, 0) == 0) // All zombies defeated
var anyInitialInfectedAlive = EntityQuery<InitialInfectedComponent, MobStateComponent>(false)
.Any(x => x.Item2.CurrentState != MobState.Dead);
var anyLivingZombies = EntityQuery<ZombieComponent, MobStateComponent>(false)
.Any(x => x.Item2.CurrentState != MobState.Dead);
var anyPendingZombies = EntityQuery<PendingZombieComponent>(false).Any();
// All II turned/dead, all entities that have turned are dead, and there are no more pending zombies
if (!anyInitialInfectedAlive && !anyLivingZombies && !anyPendingZombies)
{
_roundEnd.DoRoundEndBehavior(zombieRuleComponent.ZombieRoundEndBehavior, zombieRuleComponent.ZombieShuttleDelay);
zombieRuleComponent.ZombieRoundEndBehavior = RoundEndBehavior.Nothing; // stop this check in the future
}
// END DeltaV
if (infectedPercent > zombieRuleComponent.ZombieShuttleCallPercentage && !_roundEnd.IsRoundEndRequested()) // DeltaV - Move GetInfectedFraction to var
if (GetInfectedFraction(false) > zombieRuleComponent.ZombieShuttleCallPercentage && !_roundEnd.IsRoundEndRequested())
{
foreach (var station in _station.GetStations())
{
+10 -1
View File
@@ -41,6 +41,7 @@ using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Content.Server.Mobs; // Starlight
namespace Content.Server.Ghost
{
@@ -619,7 +620,15 @@ namespace Content.Server.Ghost
_damageable.GetTotalDamage((playerEntity.Value, damageable));
}
DamageSpecifier damage = new(_prototypeManager.Index(AsphyxiationDamageType), dealtDamage);
// Starlight - Start
//DamageSpecifier damage = new(_prototypeManager.Index(AsphyxiationDamageType), dealtDamage);
var damageType = _prototypeManager.Index(AsphyxiationDamageType);
if (TryComp<DeathgaspComponent>(playerEntity, out var deathgasp))
damageType = _prototypeManager.Index(deathgasp.DamageType);
DamageSpecifier damage = new(damageType, dealtDamage);
// Starlight - End
_damageable.ChangeDamage(playerEntity.Value, damage, true);
}
+9 -1
View File
@@ -1,4 +1,6 @@
using Content.Shared.Chat.Prototypes;
using Content.Shared.Chat.Prototypes; // Starlight
using Content.Shared.Damage.Prototypes; // Starlight
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Mobs;
@@ -21,4 +23,10 @@ public sealed partial class DeathgaspComponent : Component
/// </summary>
[DataField]
public bool NeedsCritical = true;
/// <summary>
/// Starlight - The damage that is taken when succumbing
/// </summary>
[DataField]
public ProtoId<DamageTypePrototype> DamageType = "Asphyxiation";
}
@@ -55,9 +55,13 @@ public sealed class PseudoItemSystem : SharedPseudoItemSystem
protected override void OnGettingPickedUpAttempt(EntityUid uid, PseudoItemComponent component, GettingPickedUpAttemptEvent args)
{
// Floof - changed this a bit to actually start a do-after
// Try to pick the entity up instead first
if (args.User != args.Item && _carrying.TryCarry(args.User, uid))
if (args.User != args.Item
&& TryComp<CarriableComponent>(uid, out var carriable)
&& _carrying.CanCarry(args.User, (uid, carriable)))
{
_carrying.StartCarryDoAfter(args.User, (uid, carriable));
args.Cancel();
return;
}
@@ -209,20 +209,24 @@ namespace Content.Server.Psionics.Glimmer
private void OnDestroyed(EntityUid uid, SharedGlimmerReactiveComponent component, DestructionEventArgs args)
{
Spawn("MaterialBluespace1", Transform(uid).Coordinates);
var proberCoords = Transform(uid).Coordinates;
var tier = _glimmerSystem.GetGlimmerTier();
if (tier < GlimmerTier.High)
return;
var totalIntensity = (float) (_glimmerSystem.Glimmer * 2);
var slope = (float) (11 - _glimmerSystem.Glimmer / 100);
var maxIntensity = 20;
var explosionMultiplier = 2;
if (_glimmerSystem.GetGlimmerTier() == GlimmerTier.Critical) // YOU DONE FUCKED UP
explosionMultiplier = 3;
var removed = (float) _glimmerSystem.Glimmer * _random.NextFloat(0.06f, 0.08f);
_glimmerSystem.Glimmer -= (int) removed;
var totalIntensity = (float)(_glimmerSystem.Glimmer * explosionMultiplier);
var slope = (float)(11 - _glimmerSystem.Glimmer / 100);
var maxIntensity = 75; // Same as syndicate bomb
var removed = _glimmerSystem.Glimmer * _random.NextFloat(0.06f, 0.08f);
_glimmerSystem.Glimmer -= (int)removed;
BeamRandomNearProber(uid, _glimmerSystem.Glimmer / 350, _glimmerSystem.Glimmer / 50);
_explosionSystem.QueueExplosion(uid, "Default", totalIntensity, slope, maxIntensity);
_explosionSystem.QueueExplosion(uid, "Default", totalIntensity, slope, maxIntensity, addLog: true);
Spawn("MaterialBluespace1", proberCoords); // Congrats on your bluespace!
}
private void OnUnanchorAttempt(EntityUid uid, SharedGlimmerReactiveComponent component, UnanchorAttemptEvent args)
@@ -230,7 +234,7 @@ namespace Content.Server.Psionics.Glimmer
if (component.Locked)
{
_sharedAudioSystem.PlayPvs(component.ShockNoises, args.User);
_electrocutionSystem.TryDoElectrocution(args.User, null, _glimmerSystem.Glimmer / 200, TimeSpan.FromSeconds((float) _glimmerSystem.Glimmer / 100), false);
_electrocutionSystem.TryDoElectrocution(args.User, uid, _glimmerSystem.Glimmer / 200, TimeSpan.FromSeconds((float) _glimmerSystem.Glimmer / 100), false);
args.Cancel();
}
}
@@ -184,7 +184,8 @@ public sealed class OracleSystem : EntitySystem
while (i != 0)
{
Spawn("MaterialBluespace1", Transform(user).Coordinates);
var entityToSpawn = _random.Next(0, 2) == 0 ? "MaterialBluespace1" : "CrystalNormality";
Spawn(entityToSpawn, Transform(user).Coordinates);
i--;
}
@@ -75,8 +75,7 @@ public sealed partial class CosmicFinaleComponent : Component
{ "Blunt", 2.25},
{ "Cold", 2.25},
{ "Radiation", 2.25},
{ "Asphyxiation", 2.25},
{ "Ion", 2.25}
{ "Asphyxiation", 2.25}
}
};
}
@@ -174,7 +174,7 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
if (!EntityIsCultist(args.Equipee))
{
_statusEffects.TryAddStatusEffect<CosmicEntropyDebuffComponent>(args.Equipee, EntropicDegen, TimeSpan.FromDays(1), true); // TimeSpan.MaxValue causes a crash here, so we use FromDays(1) instead.
if (TryComp<CosmicEntropyDebuffComponent>(args.Equipee, out var comp)) comp.Degen = new(){DamageDict = new(){{"Cold", 0.5}, {"Asphyxiation", 1.5}, {"Ion", 1.5}}};
if (TryComp<CosmicEntropyDebuffComponent>(args.Equipee, out var comp)) comp.Degen = new(){DamageDict = new(){{"Cold", 0.5}, {"Asphyxiation", 1.5}}};
}
}
@@ -188,7 +188,7 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
if (!EntityIsCultist(args.User))
{
_statusEffects.TryAddStatusEffect<CosmicEntropyDebuffComponent>(args.User, EntropicDegen, TimeSpan.FromDays(1), true);
if (TryComp<CosmicEntropyDebuffComponent>(args.User, out var comp)) comp.Degen = new(){DamageDict = new(){{"Cold", 0.5}, {"Asphyxiation", 1.5}, {"Ion", 1.5}}};
if (TryComp<CosmicEntropyDebuffComponent>(args.User, out var comp)) comp.Degen = new(){DamageDict = new(){{"Cold", 0.5}, {"Asphyxiation", 1.5}}};
_popup.PopupEntity(Loc.GetString("cosmiccult-gear-pickup", ("ITEM", args.Equipped)), args.User, args.User, PopupType.MediumCaution);
}
}
@@ -75,8 +75,7 @@ public sealed class CosmicRiftSystem : EntitySystem
if (TryComp<CosmicEntropyDebuffComponent>(mob, out var debuff)) debuff.Degen =
new(){DamageDict = new(){
{"Cold", 0.05 * damageMultiplier},
{"Asphyxiation", 0.15 * damageMultiplier},
{"Ion", 0.15 * damageMultiplier}
{"Asphyxiation", 0.15 * damageMultiplier}
}};
}
}
@@ -1,5 +0,0 @@
using Content.Shared._DV.Silicons;
namespace Content.Server._DV.Silicons;
public sealed class SiliconEmpSystem : SharedSiliconEmpSystem;
@@ -109,8 +109,10 @@ public sealed class FugitiveRule : StationEventSystem<FugitiveRuleComponent>
var report = new FormattedMessage();
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-title"));
report.PushNewline();
report.PushNewline();
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-first-line"));
report.PushNewline();
report.PushNewline();
if (!TryComp<HumanoidProfileComponent>(uid, out var humanoid))
{
@@ -121,22 +123,28 @@ public sealed class FugitiveRule : StationEventSystem<FugitiveRuleComponent>
var species = PrototypeManager.Index(humanoid.Species);
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-morphotype", ("species", Loc.GetString(species.Name))));
report.PushNewline();
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-age", ("age", humanoid.Age)));
report.PushNewline();
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-sex", ("sex", humanoid.Sex)));
report.PushNewline();
if (TryComp<PhysicsComponent>(uid, out var physics))
{
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-weight", ("weight", Math.Round(physics.FixturesMass))));
report.PushNewline();
}
// add a random identifying quality that officers can use to track them down
report.AddMarkupOrThrow(RobustRandom.Next(0, 2) switch
{
0 => Loc.GetString("fugitive-report-detail-dna", ("dna", GetDNA(uid))),
_ => Loc.GetString("fugitive-report-detail-prints", ("prints", GetPrints(uid)))
});
report.PushNewline();
report.PushNewline();
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-crimes-header"));
report.PushNewline();
// generate some random crimes to avoid this situation
// "officer what are my charges?"
// "uh i dunno a piece of paper said to arrest you thats it"
@@ -172,6 +180,7 @@ public sealed class FugitiveRule : StationEventSystem<FugitiveRuleComponent>
{
var count = RobustRandom.Next(rule.MinCounts, rule.MaxCounts + 1);
report.AddMarkupOrThrow(Loc.GetString("fugitive-report-crime", ("crime", Loc.GetString(crime)), ("count", count)));
report.PushNewline();
}
}
}
@@ -0,0 +1,44 @@
using Content.Shared.Store;
using Content.Shared.Store.Components;
using Robust.Shared.Prototypes;
namespace Content.Server._DV.Store.Conditions;
/// <summary>
/// XOR (eXclusive-OR) Buy Condition
/// A condition where that blocks buying a listing if another listing
/// specified is bought before it. Used to enforce that a traitor
/// can only buy 1 of X options.
///
/// Primarily used for choose-your-own-adventure DAGD Implants.
/// </summary>
public sealed partial class XORBuyCondition : ListingCondition
{
/// <summary>
/// Listing(s) that if bought, block this purchase, if any.
/// </summary>
[DataField(required: true)]
public HashSet<ProtoId<ListingPrototype>>? Listings;
public override bool Condition(ListingConditionArgs args)
{
if (!args.EntityManager.TryGetComponent<StoreComponent>(args.StoreEntity, out var storeComp))
return false;
var allListings = storeComp.FullListingsCatalog;
if (Listings != null)
{
foreach (var blacklistListing in Listings)
{
foreach (var listing in allListings)
{
if (listing.ID == blacklistListing.Id && listing.PurchaseAmount > 0)
return false; // it was purchased, so return false to fail the condition
}
}
}
return true; // If no purchases were found, return true
}
}
+163
View File
@@ -0,0 +1,163 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Numerics;
using System.Text.RegularExpressions;
using Content.Server.Administration;
using Content.Shared.Administration;
using Robust.Shared.Console;
using Robust.Shared.Maths;
using Robust.Shared.Toolshed;
using Robust.Shared.Toolshed.Errors;
using Robust.Shared.Utility;
namespace Content.Server._DV.Toolshed;
/// <summary>
/// An extended version of the engine's <c>do</c> command. Runs a console command once per piped value,
/// substituting <c>$NAME</c> tokens in the command string first.
/// </summary>
/// <remarks>
/// On top of the built-in tokens that <c>do</c> supports (<c>$ID</c>, <c>$PID</c>, <c>$WX</c>, <c>$WY</c>,
/// <c>$LX</c>, <c>$LY</c>, <c>$SELF</c>), any other <c>$name</c> is resolved as a toolshed variable and
/// converted to a string. Tokens that don't resolve to anything are left untouched.
///
/// Where the command actually runs is explicit:
/// <list type="bullet">
/// <item><c>doext:client</c> sends it back down to the calling user's own client to run locally. This is what
/// you want for client-side commands like <c>exec</c>, which resolve paths against the client's user data.</item>
/// <item><c>doext:server</c> runs it server-side as the calling session, like <c>do</c> does.</item>
/// </list>
/// </remarks>
/// <example><code>
/// self doext:client "exec /Script_$var.txt"
/// i 5 => $count; self doext:server "somecommand $count"
/// </code></example>
[ToolshedCommand(Name = "doext"), AdminCommand(AdminFlags.Debug)]
public sealed class DoExtCommand : ToolshedCommand
{
/// <summary>
/// Matches a <c>$name</c> token. Names use the same character set as toolshed variable names, so this
/// matches whole identifiers - <c>$IDLE</c> resolves as "IDLE" rather than being mangled into <c>$ID</c>.
/// </summary>
private static readonly Regex TokenRegex = new(@"\$(\w+)", RegexOptions.Compiled);
[Dependency] private readonly IConsoleHost _console = default!;
private SharedTransformSystem? _xform;
/// <summary>
/// Sends the command back down to the calling user's client, which runs it locally.
/// </summary>
[CommandImplementation("client"), TakesPipedTypeAsGeneric]
public IEnumerable<T> Client<T>(IInvocationContext ctx, [PipedArgument] IEnumerable<T> input, string command)
{
// No session means there's no client to hand this back to - e.g. the server console.
if (ctx.Session is not { } session)
{
ctx.ReportError(new NoClientSessionError());
yield break;
}
foreach (var value in input)
{
_console.RemoteExecuteCommand(session, Substitute(command, value, ctx));
yield return value;
}
}
/// <summary>
/// Runs the command on the server as the calling session.
/// </summary>
[CommandImplementation("server"), TakesPipedTypeAsGeneric]
public IEnumerable<T> Server<T>(IInvocationContext ctx, [PipedArgument] IEnumerable<T> input, string command)
{
foreach (var value in input)
{
_console.ExecuteCommand(ctx.Session, Substitute(command, value, ctx));
yield return value;
}
}
private string Substitute<T>(string command, T value, IInvocationContext ctx)
{
return TokenRegex.Replace(command, match =>
{
var name = match.Groups[1].Value;
if (TryGetBuiltin(name, value, ctx, out var builtin))
return builtin;
// Anything else is looked up as a toolshed variable and implicitly stringified.
if (ctx.ReadVar(name) is { } variable)
return Stringify(variable);
// Unresolved, so leave the token alone rather than silently blanking it.
return match.Value;
});
}
private bool TryGetBuiltin<T>(string name, T value, IInvocationContext ctx, [NotNullWhen(true)] out string? result)
{
switch (name)
{
case "SELF":
result = Stringify(value);
return true;
case "PID":
result = (ctx.Session?.AttachedEntity ?? EntityUid.Invalid).ToString();
return true;
}
// The remaining tokens are all positional, so they only apply when piping entities.
if (value is not EntityUid uid)
{
result = null;
return false;
}
switch (name)
{
case "ID":
result = uid.ToString();
return true;
case "WX":
result = Number(WorldPosition(uid).X);
return true;
case "WY":
result = Number(WorldPosition(uid).Y);
return true;
case "LX":
result = Number(Transform(uid).Coordinates.X);
return true;
case "LY":
result = Number(Transform(uid).Coordinates.Y);
return true;
}
result = null;
return false;
}
private Vector2 WorldPosition(EntityUid uid)
{
_xform ??= GetSys<SharedTransformSystem>();
return _xform.GetWorldPosition(uid);
}
private static string Number(float value) => value.ToString(CultureInfo.InvariantCulture);
private static string Stringify(object? value) => value?.ToString() ?? string.Empty;
}
public sealed class NoClientSessionError : IConError
{
public FormattedMessage DescribeInner()
{
return FormattedMessage.FromUnformatted("There is no client to run this on. doext:client must be run by a player, not the server console.");
}
public string? Expression { get; set; }
public Vector2i? IssueSpan { get; set; }
public StackTrace? Trace { get; set; }
}
+136
View File
@@ -0,0 +1,136 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using Content.Server.Administration;
using Content.Shared.Administration;
using Robust.Shared.Console;
using Robust.Shared.Maths;
using Robust.Shared.Toolshed;
using Robust.Shared.Toolshed.Errors;
using Robust.Shared.Toolshed.Syntax;
using Robust.Shared.Toolshed.TypeParsers;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
namespace Content.Server._DV.Toolshed;
/// <summary>
/// Reads the value of a single field or property off of the piped input, by name.
/// Member names are resolved the same way <c>vvread</c> does: the member must be exposed
/// via <c>[ViewVariables]</c>, <c>[DataField]</c>, or <c>[IncludeDataField]</c>.
/// </summary>
/// <example><code>ent 12345 . Name</code></example>
[ToolshedCommand(Name = "."), AdminCommand(AdminFlags.Debug)]
public sealed class FieldCommand : ToolshedCommand
{
[CommandImplementation]
public object? Field([PipedArgument] object? value, [CommandArgument(typeof(FieldNameParser))] string field, IInvocationContext ctx)
{
if (value == null)
{
ctx.ReportError(new NullInputFieldError());
return null;
}
var type = value.GetType();
var member = GetSingleMember(type, field);
// Restrict to members that vvread would let you read, so this can't be used to peek at arbitrary internals.
if (member == null || !ViewVariablesUtility.TryGetViewVariablesAccess(member, out _))
{
ctx.ReportError(new NoSuchFieldError(type, field));
return null;
}
return member switch
{
FieldInfo f => f.GetValue(value),
PropertyInfo p => p.GetValue(value),
_ => null,
};
}
/// <summary>
/// Finds the field or property with the given name, mirroring the resolution used by <c>vvread</c>.
/// </summary>
private static MemberInfo? GetSingleMember(Type type, string member)
{
var members = type
.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(m => m.Name == member && m is FieldInfo or PropertyInfo)
.ToArray();
if (members.Length == 0)
return null;
// In case there's member hiding going on, grab the one declared by the type of the object by default.
return members.Length > 1
? members.FirstOrDefault(m => m.DeclaringType == type) ?? members[0]
: members[0];
}
}
/// <summary>
/// Parses a field name as a bare identifier (letters, digits, underscore) so that the <c>.</c> command doesn't
/// require the name to be wrapped in quotes like the default <see cref="string"/> parser does.
/// </summary>
public sealed class FieldNameParser : CustomTypeParser<string>
{
public override bool TryParse(ParserContext ctx, [NotNullWhen(true)] out string? result)
{
ctx.ConsumeWhitespace();
result = ctx.GetWord(ParserContext.IsToken);
if (result != null)
return true;
if (ctx.PeekRune() is null)
ctx.Error = new OutOfInputError();
else
ctx.Error = new InvalidFieldNameError();
ctx.Error.Contextualize(ctx.Input, (ctx.Index, ctx.Index + 1));
return false;
}
public override CompletionResult? TryAutocomplete(ParserContext ctx, CommandArgument? arg)
{
return CompletionResult.FromHint(GetArgHint(arg));
}
}
public sealed class InvalidFieldNameError : IConError
{
public FormattedMessage DescribeInner()
{
return FormattedMessage.FromUnformatted("Expected a field name (letters, digits, or underscores).");
}
public string? Expression { get; set; }
public Vector2i? IssueSpan { get; set; }
public StackTrace? Trace { get; set; }
}
public sealed class NullInputFieldError : IConError
{
public FormattedMessage DescribeInner()
{
return FormattedMessage.FromUnformatted("Cannot read a field off of a null input.");
}
public string? Expression { get; set; }
public Vector2i? IssueSpan { get; set; }
public StackTrace? Trace { get; set; }
}
public sealed class NoSuchFieldError(Type type, string field) : IConError
{
public FormattedMessage DescribeInner()
{
return FormattedMessage.FromUnformatted($"Type {type.Name} has no readable field or property named '{field}'. It must be exposed via [ViewVariables], [DataField], or [IncludeDataField].");
}
public string? Expression { get; set; }
public Vector2i? IssueSpan { get; set; }
public StackTrace? Trace { get; set; }
}
@@ -0,0 +1,5 @@
using Content.Shared._Floof.OfferItem;
namespace Content.Server._Floof.OfferItem;
public sealed partial class OfferItemSystem : SharedOfferItemSystem;
@@ -13,7 +13,7 @@ public sealed partial class RevenantStasisComponent : Component
public Entity<RevenantComponent> Revenant;
[ViewVariables(VVAccess.ReadOnly)]
public TimeSpan StasisDuration = TimeSpan.FromSeconds(60);
public TimeSpan StasisDuration = TimeSpan.FromSeconds(100); // DeltaV - change from 60 to 100s
public RevenantStasisComponent(TimeSpan stasisDuration, Entity<RevenantComponent> revenant)
{
@@ -27,6 +27,7 @@ using Content.Shared.Mobs;
using Robust.Shared.Timing;
using Content.Shared.Construction.Components;
using Content.Shared.Trigger.Components;
using Content.Shared.Zombies; // DeltaV
namespace Content.Server._Impstation.Revenant.EntitySystems;
@@ -196,6 +197,7 @@ public sealed partial class RevenantAnimatedSystem : EntitySystem
animate.EndTime = _gameTiming.CurTime + duration.Value;
else if (revenant != null)
animate.EndTime = _gameTiming.CurTime + revenant.Value.Comp.AnimateTime;
EnsureComp<ZombieImmuneComponent>(target); // DeltaV - ensure immune from zombies so we don't break clients
return true;
}
+290
View File
@@ -0,0 +1,290 @@
using Content.Shared.Humanoid;
using Content.Shared.Alert;
using Robust.Server.GameObjects;
using Content.Shared.Examine;
using Robust.Server.Containers;
using Content.Shared._Starlight;
using Content.Shared.Damage.Components;
using Content.Shared.Mobs;
using Content.Shared.Movement.Systems;
using Content.Shared.Movement.Components;
using Content.Shared.Damage;
using Content.Server.Chat.Managers;
using Content.Shared.Damage.Systems;
using Content.Shared._Goobstation.Overlays;
using Robust.Shared.Timing;
using Content.Server.Body.Components;
using System.Linq;
using Content.Shared._Goobstation.Flashbang;
using Content.Shared._Starlight.Flash.Components;
using Content.Shared.Body.Components;
using Content.Shared.Flash; // Delta V - Flash Work
namespace Content.Server._Starlight;
public sealed class ShadekinSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly ExamineSystemShared _examine = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly MovementSpeedModifierSystem _speed = default!;
[Dependency] private readonly SharedFlashSystem _flashSystem = default!;
private sealed class LightCone
{
public float Direction { get; set; }
public float InnerWidth { get; set; }
public float OuterWidth { get; set; }
}
private readonly Dictionary<string, List<LightCone>> lightMasks = new()
{
["/Textures/Effects/LightMasks/cone.png"] = new List<LightCone>
{
new LightCone { Direction = 0, InnerWidth = 30, OuterWidth = 60 }
},
["/Textures/Effects/LightMasks/double_cone.png"] = new List<LightCone>
{
new LightCone { Direction = 0, InnerWidth = 30, OuterWidth = 60 },
new LightCone { Direction = 180, InnerWidth = 30, OuterWidth = 60 }
}
};
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ShadekinComponent, ComponentStartup>(OnInit);
SubscribeLocalEvent<ShadekinComponent, EyeColorInitEvent>(OnEyeColorChange);
SubscribeLocalEvent<ShadekinComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeedModifiers);
SubscribeLocalEvent<ShadekinComponent, AfterFlashedEvent>(OnShadekinFlashed); // Delta V - Prevent Chain Flashing
SubscribeLocalEvent<ShadekinComponent, FlashDurationMultiplierEvent>(GetFlashModifier); // Delta V - Flash Modifier to Shadekin
}
private void OnInit(EntityUid uid, ShadekinComponent component, ComponentStartup args)
{
UpdateAlert(uid, component, (short)component.CurrentState);
RemComp<InternalsComponent>(uid);
}
private void OnEyeColorChange(EntityUid uid, ShadekinComponent component, EyeColorInitEvent args)
{
if (!TryComp<HumanoidProfileComponent>(uid, out var humanoid))
return;
// humanoid.EyeColor = Color.Black;
Dirty(uid, humanoid);
}
public void UpdateAlert(EntityUid uid, ShadekinComponent component, short state)
{
_alerts.ShowAlert(uid, component.ShadekinAlert, state);
}
private Angle GetAngle(EntityUid lightUid, SharedPointLightComponent lightComp, EntityUid targetUid)
{
var (lightPos, lightRot) = _transform.GetWorldPositionRotation(lightUid);
lightPos += lightRot.RotateVec(lightComp.Offset);
var (targetPos, targetRot) = _transform.GetWorldPositionRotation(targetUid);
var mapDiff = targetPos - lightPos;
var oppositeMapDiff = (-lightRot).RotateVec(mapDiff);
var angle = oppositeMapDiff.ToWorldAngle();
if (angle == double.NaN && _transform.ContainsEntity(targetUid, lightUid) || _transform.ContainsEntity(lightUid, targetUid))
{
angle = 0f;
}
return angle;
}
/// <summary>
/// Return an illumination float value with is how many "energy" of light is hitting our ent.
/// WARNING: This function might be expensive, Avoid calling it too much and CACHE THE RESULT!
/// </summary>
/// <param name="uid"></param>
/// <returns></returns>
public float GetLightExposure(EntityUid uid)
{
var illumination = 0f;
var lightQuery = _lookup.GetEntitiesInRange<PointLightComponent>(Transform(uid).Coordinates, 20, LookupFlags.Uncontained);
foreach (var light in lightQuery)
{
if (!light.Comp.Enabled
|| light.Comp.Radius < 1
|| light.Comp.Energy <= 0)
continue;
var (lightPos, lightRot) = _transform.GetWorldPositionRotation(light);
lightPos += lightRot.RotateVec(light.Comp.Offset);
if (!_examine.InRangeUnOccluded(light, uid, light.Comp.Radius, null))
continue;
Transform(uid).Coordinates.TryDistance(EntityManager, Transform(light).Coordinates, out var dist);
var denom = dist / light.Comp.Radius;
var attenuation = 1 - (denom * denom);
var calculatedLight = 0f;
if (light.Comp.MaskPath is not null)
{
var angleToTarget = GetAngle(light, light.Comp, uid);
foreach (var cone in lightMasks[light.Comp.MaskPath])
{
var coneLight = 0f;
var angleAttenuation = (float)Math.Min((float)Math.Max(cone.OuterWidth - angleToTarget, 0f), cone.InnerWidth) / cone.OuterWidth;
if (angleToTarget.Degrees - cone.Direction > cone.OuterWidth)
continue;
else if (angleToTarget.Degrees - cone.Direction > cone.InnerWidth
&& angleToTarget.Degrees - cone.Direction < cone.OuterWidth)
coneLight = light.Comp.Energy * attenuation * attenuation * angleAttenuation;
else
coneLight = light.Comp.Energy * attenuation * attenuation;
calculatedLight = Math.Max(calculatedLight, coneLight);
}
}
else
calculatedLight = light.Comp.Energy * attenuation * attenuation;
illumination += calculatedLight; //Math.Max(illumination, calculatedLight);
}
return illumination;
}
private void SetPassiveBuff(EntityUid uid, ShadekinState state)
{
if (!TryComp<PassiveDamageComponent>(uid, out var passive))
return;
if (state == ShadekinState.Extreme || state == ShadekinState.Annoying || state == ShadekinState.High)
{
// passive.DamageCap = 1;
}
else if (state == ShadekinState.Low)
{
// passive.DamageCap = 20;
passive.AllowedStates.Clear();
passive.AllowedStates.Add(MobState.Alive);
passive.Interval = 1f;
}
else if (state != ShadekinState.Dark)
{
// passive.DamageCap = 0;
passive.AllowedStates.Clear();
passive.AllowedStates.Add(MobState.Alive);
passive.AllowedStates.Add(MobState.Critical);
passive.AllowedStates.Add(MobState.Dead);
passive.Interval = 0.5f;
}
}
private void ToggleNightVision(EntityUid uid, ShadekinState state)
{
if (state == ShadekinState.Dark)
{
var nightVisionComponent = EnsureComp<NightVisionComponent>(uid);
nightVisionComponent.Color = Color.FromHex("#808080"); // Delta V - Change Night Vision Color
}
else
{
if (TryComp<NightVisionComponent>(uid, out var nightVision) && nightVision.IsActive)
_flashSystem.Flash(uid, uid, uid, TimeSpan.FromSeconds(0.5 * (int)state), 0.5f);
RemComp<NightVisionComponent>(uid);
}
}
private void ApplyLightDamage(EntityUid uid, float dmg)
{
var damage = new DamageSpecifier();
damage.DamageDict.Add("Heat", dmg);
_damageable.TryChangeDamage(uid, damage, true, false);
}
private void OnRefreshMovementSpeedModifiers(EntityUid uid, ShadekinComponent component, RefreshMovementSpeedModifiersEvent args)
{
if (component.CurrentState == ShadekinState.Low || component.CurrentState == ShadekinState.Annoying ||
component.CurrentState == ShadekinState.Dark || component.CurrentState == ShadekinState.Invalid)
return;
if (!TryComp<MovementSpeedModifierComponent>(uid, out var movement))
return;
var sprintDif = movement.BaseWalkSpeed / movement.BaseSprintSpeed;
args.ModifySpeed(1f, sprintDif);
}
private ShadekinState GetStateByThreshold(ShadekinComponent component, float lightExposure)
{
var returnState = ShadekinState.Dark;
foreach (var (threshold, shadekinState) in component.Thresholds.Reverse())
{
if (threshold <= lightExposure)
{
returnState = shadekinState;
break;
}
}
return returnState;
}
// Delta V - Begin Shadekin Flash Changes
private void GetFlashModifier(EntityUid uid, ShadekinComponent comp, FlashDurationMultiplierEvent args)
{
if (!TryComp<FlashModifierComponent>(uid, out var flashModifier))
return;
args.Multiplier = flashModifier.Modifier;
}
private void OnShadekinFlashed(EntityUid uid, ShadekinComponent comp, AfterFlashedEvent ev)
{
RemComp<NightVisionComponent>(uid);
}
// Delta V - End
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<ShadekinComponent>();
while (query.MoveNext(out var uid, out var component))
{
if (_timing.CurTime < component.NextUpdate)
continue;
component.NextUpdate = _timing.CurTime + component.UpdateCooldown;
var lightExposure = 0f;
if (!_container.IsEntityInContainer(uid))
lightExposure = GetLightExposure(uid);
component.CurrentState = GetStateByThreshold(component, lightExposure);
UpdateAlert(uid, component, (short)component.CurrentState);
SetPassiveBuff(uid, component.CurrentState);
ToggleNightVision(uid, component.CurrentState);
_speed.RefreshMovementSpeedModifiers(uid);
if (component.CurrentState == ShadekinState.Extreme)
ApplyLightDamage(uid, 5);
}
}
}
@@ -23,6 +23,8 @@ using Robust.Shared.Timing;
using Content.Shared._DV.Access.Systems;
using Content.Shared._DV.Access.Components;
using Content.Shared.Mind; // DeltaV - Subdermal ID Cards
using Content.Shared.Ninja.Components; // DeltaV
using Content.Shared.Revenant.Components; // DeltaV
namespace Content.Shared.Access.Systems;
@@ -31,7 +33,6 @@ public sealed class AccessReaderSystem : EntitySystem
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly EmagSystem _emag = default!;
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly SharedGameTicker _gameTicker = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
@@ -151,7 +152,7 @@ public sealed class AccessReaderSystem : EntitySystem
private void OnEmagged(EntityUid uid, AccessReaderComponent reader, ref GotEmaggedEvent args)
{
if (!_emag.CompareFlag(args.Type, EmagType.Interaction)) // DeltaV - emag for lockers etc instead of doorjack
if (HasComp<SpaceNinjaComponent>(args.UserUid) || HasComp<RevenantComponent>(args.UserUid)) // DeltaV - Don't break access if its a ninja doing it
return;
if (!reader.BreakOnAccessBreaker)
+13 -2
View File
@@ -100,6 +100,12 @@ public abstract partial class SharedVisualBodySystem : EntitySystem
if (!other.Layer.Equals(ent.Comp.Layer))
return;
// Delta V - Begin Fix Height for Cloning
var height = other.Profile.Height;
if (TryComp<HumanoidProfileComponent>(args.Body.Owner, out var component))
ScaleBody((args.Body.Owner, component), height, height);
// Delta V - End
SetOrganAppearance(ent, other.Data);
}
@@ -112,9 +118,14 @@ public abstract partial class SharedVisualBodySystem : EntitySystem
var height = Math.Clamp(MathF.Round(args.Base.Value.Height, 2), speciesPrototype.MinHeight, speciesPrototype.MaxHeight);
ScaleBody(entity, speciesPrototype.ScaleHeight ? height : 1f, height);
}
private void ScaleBody(Entity<HumanoidProfileComponent> entity, float heightX, float heightY)
{
_scaleVisualsSystem.SetSpriteScale(
entity.Owner,
new Vector2(speciesPrototype.ScaleHeight ? height : 1f, height)
new Vector2(heightX, heightY)
);
}
// Delta V - END
@@ -148,7 +159,7 @@ public abstract partial class SharedVisualBodySystem : EntitySystem
if (ent.Comp.Layer.Equals(HumanoidVisualLayers.Eyes))
{
// Delta V - Begin Add AppearanceLoaded Event
var appearanceLoaded = new AppearanceLoadedEvent(ent.Comp.Profile.EyeColor);
var appearanceLoaded = new AppearanceLoadedEvent(ent.Comp.Profile.EyeColor, ent.Comp.Profile.SkinColor);
RaiseLocalEvent(args.Body.Owner, ref appearanceLoaded);
// Delta V - End
SetOrganColor(ent, ent.Comp.Profile.EyeColor);
+15 -1
View File
@@ -28,4 +28,18 @@ public readonly partial record struct CargoBountyData
Bounty = bounty.ID;
Id = $"{bounty.IdPrefix}{uniqueIdentifier:D3}";
}
}
// Begin DeltaV bounty claiming
[DataField]
public string ClaimedBy { get; init; } = string.Empty;
[DataField]
public CargoBountyStatus Status { get; init; } = CargoBountyStatus.Undelivered;
}
public enum CargoBountyStatus
{
Undelivered,
Waiting,
OnShuttle,
} // End DeltaV bounty claiming
@@ -94,3 +94,4 @@ public sealed class BountySkipMessage : BoundUserInterfaceMessage
BountyId = bountyId;
}
}
+9 -24
View File
@@ -25,12 +25,6 @@ public abstract class SharedEmpSystem : EntitySystem
[Dependency] private readonly SharedPvsOverrideSystem _pvs = default!; // Frontier
[Dependency] private readonly IConfigurationManager _cfg = default!; // Frontier: EMP Blast PVS
/// <summary>
/// DeltaV. Default damage of EMPs, as dertermined by direction. There's no good component to put
/// this on so its defined here.
/// </summary>
private static readonly DamageSpecifier? DefaultEmpDamage = new() { DamageDict = new() { { "Ion", 130 } } };
private HashSet<EntityUid> _entSet = new();
private EntityQuery<EmpResistanceComponent> _resistanceQuery;
@@ -59,12 +53,11 @@ public abstract class SharedEmpSystem : EntitySystem
/// <param name="energyConsumption">The amount of energy consumed by the EMP pulse. In Joule.</param>
/// <param name="duration">The duration of the EMP effects.</param>
/// <param name="user">The player that caused the effect. Used for predicted audio.</param>
/// <param name="damage">DeltaV - The damage that that EMP will do. If not specified or null, will do 130 Ion damage. To do no damage, pass in a DamageSpecifier with no damage types.</param>
public void EmpPulse(MapCoordinates mapCoordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null) // DeltaV - Add Ion Damage
public void EmpPulse(MapCoordinates mapCoordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null)
{
foreach (var uid in _lookup.GetEntitiesInRange(mapCoordinates, range))
{
TryEmpEffects(uid, energyConsumption, duration, user, damage ?? DefaultEmpDamage); // DeltaV - Add Ion Damage
TryEmpEffects(uid, energyConsumption, duration, user);
}
// TODO: replace with PredictedSpawn once it works with animated sprites
@@ -92,15 +85,13 @@ public abstract class SharedEmpSystem : EntitySystem
/// <param name="energyConsumption">The amount of energy consumed by the EMP pulse.</param>
/// <param name="duration">The duration of the EMP effects.</param>
/// <param name="user">The player that caused the effect. Used for predicted audio.</param>'
/// <param name="damage">DeltaV - The damage that that EMP will do. If not specified or null, will do 130 Ion damage. To do no damage, pass in a DamageSpecifier with no damage types.</param>
/// <param name="predicted">Whether this pulse is being replicated on the client.</param>
public void EmpPulse(EntityCoordinates coordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null, bool predicted = true) // Delta V - Add ion damage
public void EmpPulse(EntityCoordinates coordinates, float range, float energyConsumption, TimeSpan duration, EntityUid? user = null, bool predicted = true)
{
_entSet.Clear();
_lookup.GetEntitiesInRange(coordinates, range, _entSet);
foreach (var uid in _entSet)
{
TryEmpEffects(uid, energyConsumption, duration, user, damage ?? DefaultEmpDamage); // DeltaV - Add Ion Damage
TryEmpEffects(uid, energyConsumption, duration, user);
}
// TODO: replace with PredictedSpawn once it works with animated sprites
if (_net.IsServer)
@@ -123,37 +114,31 @@ public abstract class SharedEmpSystem : EntitySystem
/// <summary>
/// Attempts to apply the effects of an EMP pulse onto an entity by first raising an <see cref="EmpAttemptEvent"/>, followed by raising a <see cref="EmpPulseEvent"/> on it.
/// <br/>
/// <br/>DeltaV - In most cases, you will want to use <see cref="EmpPulse"/> instead.
/// </summary>
/// <param name="uid">The entity to apply the EMP effects on.</param>
/// <param name="energyConsumption">The amount of energy consumed by the EMP.</param>
/// <param name="duration">The duration of the EMP effects.</param>
/// <param name="user">The player that caused the EMP. For prediction purposes.</param>
/// <param name="damage">DeltaV - The damage that that EMP will do. If null, no damage is done.</param>
/// <returns>If the entity was affected by the EMP.</returns>
public bool TryEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null) // DeltaV - Add Ion Damage
public bool TryEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null)
{
var attemptEv = new EmpAttemptEvent();
RaiseLocalEvent(uid, ref attemptEv);
if (attemptEv.Cancelled)
return false;
return DoEmpEffects(uid, energyConsumption, duration, user, damage); // DeltaV - Add Ion Damage
return DoEmpEffects(uid, energyConsumption, duration, user);
}
/// <summary>
/// Applies the effects of an EMP pulse onto an entity by raising a <see cref="EmpPulseEvent"/> on it.
/// <br/>
/// <br/>DeltaV - In most cases, you will want to use <see cref="EmpPulse"/> instead.
/// </summary>
/// <param name="uid">The entity to apply the EMP effects on.</param>
/// <param name="energyConsumption">The amount of energy consumed by the EMP.</param>
/// <param name="duration">The duration of the EMP effects.</param>
/// <param name="user">The player that caused the EMP. For prediction purposes.</param>
/// <param name="damage">DeltaV - The damage that that EMP will do. If null, no damage is done.</param>
/// <returns>If the entity was affected by the EMP.</returns>
public bool DoEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null, DamageSpecifier? damage = null) // DeltaV - Add Ion Damage
public bool DoEmpEffects(EntityUid uid, float energyConsumption, TimeSpan duration, EntityUid? user = null)
{
var strMultiplier = 1f;
var durMultiplier = 1f;
@@ -162,7 +147,7 @@ public abstract class SharedEmpSystem : EntitySystem
strMultiplier = resistance.StrengthMultiplier;
durMultiplier = resistance.DurationMultiplier;
}
var ev = new EmpPulseEvent(energyConsumption * strMultiplier, false, false, duration * durMultiplier, user, damage); // DeltaV - Add Ion Damage
var ev = new EmpPulseEvent(energyConsumption * strMultiplier, false, false, duration * durMultiplier, user);
RaiseLocalEvent(uid, ref ev);
// TODO: replace with PredictedSpawn once it works with animated sprites
@@ -235,7 +220,7 @@ public record struct EmpAttemptEvent(bool Cancelled);
/// <param name="User">The player that caused the EMP. For prediction purposes.</param>
[ByRefEvent]
public record struct EmpPulseEvent(float EnergyConsumption, bool Affected, bool Disabled, TimeSpan Duration, EntityUid? User, DamageSpecifier? Damage = null); // DeltaV - Added Damage
public record struct EmpPulseEvent(float EnergyConsumption, bool Affected, bool Disabled, TimeSpan Duration, EntityUid? User);
/// <summary>
/// Raised on an entity after <see cref="EmpDisabledComponent"/> is removed.
+2 -1
View File
@@ -26,6 +26,7 @@ using System.Linq;
using Content.Shared.Movement.Systems;
using Content.Shared.Random.Helpers;
using Content.Shared.Clothing.Components;
using Content.Shared._Starlight.Flash.Components; // Delta V - For Flash Duration
namespace Content.Shared.Flash;
@@ -173,7 +174,7 @@ public abstract class SharedFlashSystem : EntitySystem
// Goobstation end
// don't paralyze, slowdown or convert to rev if the target is immune to flashes
if (!_statusEffectsSystem.TryAddStatusEffect<FlashedComponent>(target, FlashedKey, flashDuration, true) && !ignoreProtection) //DeltaV: allow flashing to ignore flash protection
if (!_statusEffectsSystem.TryAddStatusEffect<FlashedComponent>(target, FlashedKey, flashDuration * multiplier, true) && !ignoreProtection) //DeltaV: allow flashing to ignore flash protection. Added Flashduration Multiplier
return;
if (stunDuration != null)
@@ -68,6 +68,7 @@ namespace Content.Shared.Input
public static readonly BoundKeyFunction TakeScreenshotNoUI = "TakeScreenshotNoUI";
public static readonly BoundKeyFunction ToggleFullscreen = "ToggleFullscreen";
public static readonly BoundKeyFunction Point = "Point";
public static readonly BoundKeyFunction OfferItem = "OfferItem"; // Floofstation
public static readonly BoundKeyFunction ZoomOut = "ZoomOut";
public static readonly BoundKeyFunction ZoomIn = "ZoomIn";
public static readonly BoundKeyFunction ResetZoom = "ResetZoom";
+16
View File
@@ -103,6 +103,22 @@ public abstract class SharedItemSystem : EntitySystem
VisualsChanged(uid);
}
/// <summary>
/// DeltaV - clear item visuals
/// </summary>
public void ClearVisuals(Entity<ItemComponent?> ent)
{
if (!Resolve(ent, ref ent.Comp))
return;
ent.Comp.RsiPath = null;
ent.Comp.InhandVisuals = new();
ent.Comp.HeldPrefix = null;
Dirty(ent, ent.Comp);
VisualsChanged(ent.Owner);
}
#endregion
private void OnHandInteract(EntityUid uid, ItemComponent component, InteractHandEvent args)
@@ -1,4 +1,5 @@
using Content.Shared._ST.Interaction; // Stellar - interaction particles
using Content.Shared._Floof.OfferItem; // Floof
using Content.Shared.ActionBlocker;
using Content.Shared.Administration.Logs;
using Content.Shared.Alert;
@@ -117,10 +118,11 @@ public sealed class PullingSystem : EntitySystem
if (TryComp(args.PullerUid, out PullerComponent? pullerComp) && !pullerComp.NeedsHands)
return;
if (!_virtual.TrySpawnVirtualItemInHand(args.PulledUid, uid))
if (!_virtual.TrySpawnVirtualItemInHand(args.PulledUid, uid, out var virt)) // Floofstation - store item
{
DebugTools.Assert("Unable to find available hand when starting pulling??");
}
EnsureComp<OfferableVirtualItemComponent>(virt.Value); // Floofstation - add a special component to allow offering it
}
private void HandlePullStopped(EntityUid uid, HandsComponent component, PullStoppedMessage args)
@@ -1,8 +1,7 @@
using Content.Shared.Actions;
using Content.Shared.Bed.Sleep;
using Content.Shared.DoAfter;
using Content.Shared.Hands;
using Content.Shared.IdentityManagement;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction.Events;
using Content.Shared.Item;
using Content.Shared.Item.PseudoItem;
@@ -24,7 +23,8 @@ public abstract partial class SharedPseudoItemSystem : EntitySystem
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedContainerSystem _container = default!; // Floofstation
[Dependency] private readonly SharedHandsSystem _hands = default!; // Floofstation
private readonly ProtoId<TagPrototype> PreventTag = "PreventLabel";
private readonly EntProtoId SleepActionId = "ActionSleep"; // The action used for sleeping inside bags. Currently uses the default sleep action (same as beds)
@@ -116,17 +116,35 @@ public abstract partial class SharedPseudoItemSystem : EntitySystem
protected virtual void OnGettingPickedUpAttempt(EntityUid uid, PseudoItemComponent component,
GettingPickedUpAttemptEvent args)
{
if (args.User == args.Item)
return;
args.Cancel(); // Floof - this is a terrible idea. This triggers every time ANY system checks if a pseudo-item can be picked up.
// WHY DID YOU DO THAT, NYANOTRASEN???
_transform.AttachToGridOrMap(uid);
args.Cancel();
// if (args.User == args.Item)
// return;
//
// _transform.AttachToGridOrMap(uid);
// args.Cancel();
}
private void OnDropAttempt(EntityUid uid, PseudoItemComponent component, DropAttemptEvent args)
{
if (component.Active)
args.Cancel();
if (!component.Active)
return;
// Floof - we try to get the containing container and try to drop it into it
// If possible, we do it, since a bagged cat probably can put things back into the bag just like they can pick them up.
string? failReason = null;
if (_hands.GetActiveItem(uid) is { Valid: true, } droppedItem
&& _container.TryGetContainingContainer(Transform(uid).ParentUid, uid, out var pseudoItemContainer)
&& TryComp<StorageComponent>(pseudoItemContainer.Owner, out var targetStorage)
&& _storage.CanInsert(pseudoItemContainer.Owner, droppedItem, out failReason, targetStorage, ignoreStacks: true)
)
_storage.Insert(pseudoItemContainer.Owner, droppedItem, out _, uid, targetStorage, stackAutomatically: false);
if (failReason != null)
_popupSystem.PopupEntity(Loc.GetString(failReason), uid, uid);
args.Cancel();
}
private void OnInsertAttempt(EntityUid uid, PseudoItemComponent component,
@@ -141,8 +159,9 @@ public abstract partial class SharedPseudoItemSystem : EntitySystem
// Prevents moving within the bag :)
private void OnInteractAttempt(EntityUid uid, PseudoItemComponent component, InteractionAttemptEvent args)
{
if (args.Uid == args.Target && component.Active)
args.Cancelled = true;
// Floof - why the fuck.
// if (args.Uid == args.Target && component.Active)
// args.Cancelled = true;
}
private void OnDoAfter(EntityUid uid, PseudoItemComponent component, DoAfterEvent args)
@@ -32,7 +32,7 @@ public sealed partial class RevenantComponent : Component
public string SpawnOnDeathPrototype = "EctoplasmRevenant"; // DeltaV
[DataField("stasisTime"), ViewVariables(VVAccess.ReadWrite)] // Begin Imp Changes
public TimeSpan StasisTime = TimeSpan.FromSeconds(60);
public TimeSpan StasisTime = TimeSpan.FromSeconds(100); // DeltaV - change from 60 to 100s
/// <summary>
/// If true, only bible users can exorcise this revenant
@@ -50,7 +50,7 @@ public sealed partial class RevenantComponent : Component
/// grinder will explode.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public bool GrindingRequiresSalt = true; // End Imp Changes
public bool GrindingRequiresSalt = false; // End Imp Changes - DeltaV - true to false
/// <summary>
/// The entity's current max amount of essence. Can be increased
@@ -188,12 +188,20 @@ public abstract class SharedStorageSystem : EntitySystem
return;
}
// Begin DeltaV - the grid check excludes the item being resized because it's already in the storage which defeats the purpose so yoink it out to remove that
storage.StoredItems.Remove(itemEnt.Owner);
UpdateOccupied((container.Owner, storage));
if (!ItemFitsInGridLocation((itemEnt.Owner, itemEnt.Comp), (container.Owner, storage), loc))
if (ItemFitsInGridLocation((itemEnt.Owner, itemEnt.Comp), (container.Owner, storage), loc))
{
storage.StoredItems.Add(itemEnt.Owner, loc);
UpdateOccupied((container.Owner, storage));
}
else
{
ContainerSystem.Remove(itemEnt.Owner, container, force: true);
}
// End DeltaV - the grid check excludes the item being resized because it's already in the storage which defeats the purpose so yoink it out to remove that
}
private void OnNestedStorageCvar(bool obj)
@@ -28,10 +28,4 @@ public sealed partial class EmpOnTriggerComponent : BaseXOnTriggerComponent
/// </summary>
[DataField, AutoNetworkedField]
public TimeSpan DisableDuration = TimeSpan.FromSeconds(60);
/// <summary>
/// DeltaV - The damage dealt to silicons instead of draining their power cells
/// </summary>
[DataField, AutoNetworkedField]
public DamageSpecifier? Damage;
}
@@ -9,7 +9,7 @@ public sealed class EmpOnTriggerSystem : XOnTriggerSystem<EmpOnTriggerComponent>
protected override void OnTrigger(Entity<EmpOnTriggerComponent> ent, EntityUid target, ref TriggerEvent args)
{
_emp.EmpPulse(Transform(target).Coordinates, ent.Comp.Range, ent.Comp.EnergyConsumption, ent.Comp.DisableDuration, args.User, ent.Comp.Damage, predicted: args.Predicted); // Delta V - Silicon Damage
_emp.EmpPulse(Transform(target).Coordinates, ent.Comp.Range, ent.Comp.EnergyConsumption, ent.Comp.DisableDuration, args.User, predicted: args.Predicted);
args.Handled = true;
}
}
@@ -75,4 +75,7 @@ public sealed partial class PreenableComponent : Component
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField, AutoPausedField]
public TimeSpan? ReplenishTime;
[DataField, AutoNetworkedField]
public Color? Color;
}
@@ -1,5 +1,6 @@
using Content.Shared._DV.Body.Components;
using Content.Shared._DV.Body.Events;
using Content.Shared._DV.Humanoid;
using Content.Shared.Body.Components;
using Content.Shared.Chat;
using Content.Shared.Damage;
@@ -45,6 +46,7 @@ public sealed class PreenableSystem : EntitySystem
SubscribeLocalEvent<PreenableComponent, DamageChangedEvent>(OnDamaged);
SubscribeLocalEvent<PreenableComponent, DamageModifyEvent>(OnDamageModify);
SubscribeLocalEvent<PreenableComponent, ComponentInit>(OnCompInit);
SubscribeLocalEvent<PreenableComponent, AppearanceLoadedEvent>(OnProfileLoadFinished);
}
private void OnCompInit(Entity<PreenableComponent> ent, ref ComponentInit args)
@@ -185,7 +187,7 @@ public sealed class PreenableSystem : EntitySystem
if (TryComp<HumanoidProfileComponent>(ent, out var appearance))
{
_appearance.SetData(feather, FeatherVisuals.FeatherColor, Color.White); // TODO: Nubody Colors
_appearance.SetData(feather, FeatherVisuals.FeatherColor, ent.Comp.Color ?? Color.White);
}
// best be careful, no cleaning this
@@ -204,6 +206,11 @@ public sealed class PreenableSystem : EntitySystem
return feather;
}
private void OnProfileLoadFinished(Entity<PreenableComponent> ent, ref AppearanceLoadedEvent args)
{
ent.Comp.Color = args.SkinColor;
}
public override void Update(float deltaTime)
{
base.Update(deltaTime);
@@ -0,0 +1,31 @@
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared._DV.Cargo.Components;
[Serializable, NetSerializable]
public sealed class BountyClaimedMessage : BoundUserInterfaceMessage
{
public readonly string BountyId;
public BountyClaimedMessage(string bountyId)
{
BountyId = bountyId;
}
}
[Serializable, NetSerializable]
public sealed class BountySetStatusMessage : BoundUserInterfaceMessage
{
public readonly string BountyId;
public readonly int Status;
public BountySetStatusMessage(string bountyId, int status)
{
BountyId = bountyId;
Status = status;
}
}
+17 -12
View File
@@ -28,6 +28,7 @@ using Robust.Shared.Network;
using Robust.Shared.Physics.Components;
using System.Numerics;
using Content.Shared._DV.Polymorph;
using Content.Shared._Floof.OfferItem;
using Content.Shared.Hands.EntitySystems;
namespace Content.Shared._DV.Carrying;
@@ -181,14 +182,15 @@ public sealed class CarryingSystem : EntitySystem
/// </summary>
private void OnInteractionAttempt(Entity<BeingCarriedComponent> ent, ref InteractionAttemptEvent args)
{
if (args.Target is not {} target)
return;
var targetParent = Transform(target).ParentUid;
var carrier = ent.Comp.Carrier;
if (target != carrier && targetParent != carrier && targetParent != ent.Owner)
args.Cancelled = true;
// Floofstation - no - this prevents the person from escaping and more.
// if (args.Target is not {} target)
// return;
//
// var targetParent = Transform(target).ParentUid;
//
// var carrier = ent.Comp.Carrier;
// if (target != carrier && targetParent != carrier && targetParent != ent.Owner)
// args.Cancelled = true;
}
private void OnMoveAttempt(Entity<BeingCarriedComponent> ent, ref UpdateCanMoveEvent args)
@@ -203,8 +205,9 @@ public sealed class CarryingSystem : EntitySystem
private void OnInteractedWith(Entity<BeingCarriedComponent> ent, ref GettingInteractedWithAttemptEvent args)
{
if (args.Uid != ent.Comp.Carrier)
args.Cancelled = true;
// Floofstation - why?
// if (args.Uid != ent.Comp.Carrier)
// args.Cancelled = true;
}
private void OnPullAttempt(Entity<BeingCarriedComponent> ent, ref PullAttemptEvent args)
@@ -242,7 +245,8 @@ public sealed class CarryingSystem : EntitySystem
args.Handled = true;
}
private void StartCarryDoAfter(EntityUid carrier, Entity<CarriableComponent> carried)
// Floofstation - made public
public void StartCarryDoAfter(EntityUid carrier, Entity<CarriableComponent> carried)
{
TimeSpan length = GetPickupDuration(carrier, carried);
@@ -299,7 +303,8 @@ public sealed class CarryingSystem : EntitySystem
for (var x = 0; x < Comp<CarriableComponent>(carried).FreeHandsRequired; x++)
{
_virtualItem.TrySpawnVirtualItemInHand(carried, carrier);
if (_virtualItem.TrySpawnVirtualItemInHand(carried, carrier, out var virtualItem))
EnsureComp<OfferableVirtualItemComponent>(virtualItem.Value);
}
}
@@ -0,0 +1,15 @@
using Content.Shared.Item;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared._DV.Forensics;
[RegisterComponent, NetworkedComponent]
public sealed partial class DVExpandToInsertedItemSizeComponent : Component
{
[DataField(required: true)]
public string ItemSlot;
[DataField(required: true)]
public ProtoId<ItemSizePrototype> EmptySize;
}
@@ -0,0 +1,50 @@
using Content.Shared.Item;
using Robust.Shared.Containers;
namespace Content.Shared._DV.Forensics;
public sealed class DVExpandToInsertedItemSizeSystem : EntitySystem
{
[Dependency] private readonly SharedItemSystem _item = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVExpandToInsertedItemSizeComponent, EntInsertedIntoContainerMessage>(OnItemInserted);
SubscribeLocalEvent<DVExpandToInsertedItemSizeComponent, EntRemovedFromContainerMessage>(OnItemRemoved);
}
private void Refresh(Entity<DVExpandToInsertedItemSizeComponent> ent)
{
var slot = _container.EnsureContainer<ContainerSlot>(ent, ent.Comp.ItemSlot);
if (slot.ContainedEntity is { } contained)
{
var item = Comp<ItemComponent>(contained);
_item.SetSize(ent, item.Size);
_item.SetShape(ent, item.Shape);
}
else
{
_item.SetSize(ent, ent.Comp.EmptySize);
_item.SetShape(ent, null);
}
}
private void OnItemInserted(Entity<DVExpandToInsertedItemSizeComponent> ent, ref EntInsertedIntoContainerMessage args)
{
if (ent.Comp.ItemSlot != args.Container.ID)
return;
Refresh(ent);
}
private void OnItemRemoved(Entity<DVExpandToInsertedItemSizeComponent> ent, ref EntRemovedFromContainerMessage args)
{
if (ent.Comp.ItemSlot != args.Container.ID)
return;
Refresh(ent);
}
}
@@ -0,0 +1,17 @@
using Robust.Shared.GameStates;
using Robust.Shared.Utility;
namespace Content.Shared._DV.Forensics;
[RegisterComponent, NetworkedComponent]
public sealed partial class DVItemSlotVisualsComponent : Component
{
[DataField(required: true)]
public string ItemSlot;
[DataField(required: true)]
public SpriteSpecifier FilledSprite;
[DataField(required: true)]
public SpriteSpecifier UnfilledSprite;
}
@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;
namespace Content.Shared._DV.Forensics;
[RegisterComponent, NetworkedComponent]
public sealed partial class DVSeenInsertedItemComponent : Component
{
[DataField(required: true)]
public string ItemSlot;
}
@@ -0,0 +1,80 @@
using Content.Shared.Examine;
using Content.Shared.IdentityManagement;
using Content.Shared.Item;
using Content.Shared.NameModifier.EntitySystems;
using Robust.Shared.Containers;
using Robust.Shared.Timing;
namespace Content.Shared._DV.Forensics;
public sealed class DVSeenInsertedItemSystem : EntitySystem
{
[Dependency] private readonly NameModifierSystem _nameModifier = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedItemSystem _item = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVSeenInsertedItemComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<DVSeenInsertedItemComponent, RefreshNameModifiersEvent>(OnRefreshModifiers);
SubscribeLocalEvent<DVSeenInsertedItemComponent, EntInsertedIntoContainerMessage>(OnItemInserted);
SubscribeLocalEvent<DVSeenInsertedItemComponent, EntRemovedFromContainerMessage>(OnItemRemoved);
}
private void OnExamined(Entity<DVSeenInsertedItemComponent> ent, ref ExaminedEvent args)
{
var slot = _container.EnsureContainer<ContainerSlot>(ent, ent.Comp.ItemSlot);
if (slot.ContainedEntity is { } contained)
{
args.PushMarkup(Loc.GetString("dv-seen-inserted-item-examined.full", ("container", Identity.Entity(ent, EntityManager, args.Examiner)), ("contained", contained)));
}
else
{
args.PushMarkup(Loc.GetString("dv-seen-inserted-item-examined.empty", ("container", Identity.Entity(ent, EntityManager, args.Examiner))));
}
}
private void OnRefreshModifiers(Entity<DVSeenInsertedItemComponent> ent, ref RefreshNameModifiersEvent args)
{
var slot = _container.EnsureContainer<ContainerSlot>(ent, ent.Comp.ItemSlot);
if (slot.ContainedEntity is not { } contained)
return;
args.AddModifier("dv-seen-inserted-item-name-modifier", extraArgs: ("contained", contained));
}
private void Refresh(Entity<DVSeenInsertedItemComponent> ent)
{
_nameModifier.RefreshNameModifiers(ent.Owner);
var slot = _container.EnsureContainer<ContainerSlot>(ent, ent.Comp.ItemSlot);
if (slot.ContainedEntity is { } contained)
{
var item = Comp<ItemComponent>(contained);
_item.CopyVisuals(ent.Owner, item);
}
else
{
_item.ClearVisuals(ent.Owner);
}
}
private void OnItemInserted(Entity<DVSeenInsertedItemComponent> ent, ref EntInsertedIntoContainerMessage args)
{
if (args.Container.ID != ent.Comp.ItemSlot || _timing.ApplyingState)
return;
Refresh(ent);
}
private void OnItemRemoved(Entity<DVSeenInsertedItemComponent> ent, ref EntRemovedFromContainerMessage args)
{
if (args.Container.ID != ent.Comp.ItemSlot || _timing.ApplyingState)
return;
Refresh(ent);
}
}
@@ -4,4 +4,4 @@ namespace Content.Shared._DV.Humanoid;
/// Raised on an entity when their appearance is changed.
/// </summary>
[ByRefEvent]
public record struct AppearanceLoadedEvent(Color EyeColor);
public record struct AppearanceLoadedEvent(Color EyeColor, Color SkinColor);
@@ -1,7 +0,0 @@
namespace Content.Shared._DV.Silicons.Components;
///<summary>
///This components prevents the normal EMP effects on an entity, and makes it take ion damage instead
///</summary>
[RegisterComponent]
public sealed partial class SiliconEmpComponent : Component;
@@ -1,40 +0,0 @@
using Content.Shared.Emp;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Damage.Components;
using Content.Shared._DV.Silicons.Components;
namespace Content.Shared._DV.Silicons;
public abstract class SharedSiliconEmpSystem : EntitySystem
{
[Dependency] private readonly DamageableSystem _damageable = default!;
/// <summary>
/// If the entity has the <see cref="SiliconEmpComponent"/>, then it should take damage instead of draining its battery.
/// </summary>
/// <param name="entity">The entity to check</param>
/// <returns>true if the entity has <see cref="SiliconEmpComponent"/></returns>
public bool ShouldTakeDamageInsteadOfPowerDrain(Entity<SiliconEmpComponent?> entity)
{
if (!Resolve(entity, ref entity.Comp, false))
return false;
return true;
}
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SiliconEmpComponent, EmpPulseEvent>(OnEmpPulse);
}
private void OnEmpPulse(Entity<SiliconEmpComponent> ent, ref EmpPulseEvent args)
{
if (args.Damage is not { } damage)
return;
_damageable.TryChangeDamage(ent.Owner, damage, false);
}
}
@@ -0,0 +1,5 @@
using Content.Shared.Alert;
namespace Content.Shared._Floof.OfferItem;
public sealed partial class AcceptOfferAlertEvent : BaseAlertEvent;
@@ -0,0 +1,52 @@
using Content.Shared.Alert;
using Content.Shared.Inventory.VirtualItem;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared._Floof.OfferItem;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedOfferItemSystem))]
public sealed partial class OfferItemComponent : Component
{
/// <summary>
/// Apparently this indicates whether the entity is currently choosing an entity to offer (right after pressing F).
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool IsInOfferMode;
/// <summary>
/// If this is true, then someone is currently offering an item to this entity, and <see cref="ReceivingFrom"/>
/// stores the ID of that entity.
/// </summary>
[DataField, AutoNetworkedField]
public bool IsInReceiveMode;
[DataField, AutoNetworkedField]
public string? Hand;
[DataField, AutoNetworkedField]
public EntityUid? Item;
/// <summary>
/// Floofstation note. So, this is EE shitcode, so prepare for an emotional rollercoaster.
/// This field can mean TWO things. It's either the target entity this entity is offering an item to,
/// or an entity that is offering an item to this entity.
/// Whether it's one or the other is distinguished by <see cref="IsInReceiveMode"/>.<br/><br/>
///
/// In rare cases it can be both. According to my research, if entity A offers an item to entity B, and entity B offers to entity A,
/// then both entities will end up in receive mode, and they will have each other as targets. There's a check preventing offer loops
/// of length more than 2.
/// </summary>
[DataField, AutoNetworkedField]
public EntityUid? ReceivingFrom;
[DataField]
public float MaxOfferDistance = 2f;
[DataField]
public ProtoId<AlertPrototype> OfferAlert = "Offer";
public EntityUid GetRealEntity(EntityManager entityManager) =>
entityManager.GetComponentOrNull<VirtualItemComponent>(Item)?.BlockingEntity ?? Item ?? EntityUid.Invalid;
}
@@ -0,0 +1,11 @@
using Robust.Shared.GameStates;
namespace Content.Shared._Floof.OfferItem;
/// <summary>
/// A marker component that, when applied to a virtual item, allows it to be offered using item offering.
/// Implementors have to listen on ItemTransferredEvent.
/// </summary>
[RegisterComponent]
[NetworkedComponent]
public sealed partial class OfferableVirtualItemComponent : Component;
@@ -0,0 +1,93 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Alert;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Input;
using Content.Shared.Popups;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;
namespace Content.Shared._Floof.OfferItem;
public abstract partial class SharedOfferItemSystem
{
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
private void InitializeInteractions()
{
base.Initialize();
CommandBinds.Builder
.Bind(ContentKeyFunctions.OfferItem, InputCmdHandler.FromDelegate(SetInOfferMode, handle: false, outsidePrediction: false))
.Register<SharedOfferItemSystem>();
}
public override void Shutdown()
{
base.Shutdown();
CommandBinds.Unregister<SharedOfferItemSystem>();
}
/// <summary>
/// This sets IsInOfferMode to true, allowing the player to select whom to offer an item to with interaction.
/// </summary>
private void SetInOfferMode(ICommonSession? offerer)
{
if (offerer is not { } playerSession)
return;
if (playerSession.AttachedEntity is not { Valid: true } uid)
return;
if (!Exists(uid))
return;
if (!_actionBlocker.CanInteract(uid, null))
return;
if (!TryComp<OfferItemComponent>(uid, out var offerItem))
return;
if (!TryComp<HandsComponent>(uid, out var hands))
return;
if (_hands.GetActiveHand((uid, hands)) is not { } activeHandName)
return;
if (!_hands.TryGetHeldItem((uid, hands), activeHandName, out var heldItem))
return;
offerItem.Item = heldItem;
if (!offerItem.IsInOfferMode)
{
if (offerItem.Item == null)
{
_popup.PopupEntity(Loc.GetString("offer-item-empty-hand"), uid, uid);
return;
}
if (offerItem.Hand == null || offerItem.ReceivingFrom == null)
{
offerItem.IsInOfferMode = true;
offerItem.Hand = activeHandName;
Dirty(uid, offerItem);
return;
}
}
// If we're already offering an item to someone, cancel that offer
if (offerItem.ReceivingFrom != null)
{
UnReceive(offerItem.ReceivingFrom.Value, offererComp: offerItem);
offerItem.IsInOfferMode = false;
Dirty(uid, offerItem);
return;
}
UnOffer(uid, offerItem);
}
}
@@ -0,0 +1,414 @@
using Content.Shared._DV.Carrying;
using Content.Shared.Alert;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Movement.Pulling.Components;
using Content.Shared.Movement.Pulling.Systems;
using Content.Shared.Nutrition.EntitySystems;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Timing;
// Dear contributor.
// This system is fucking unmaintainable.
// If you ever happen to touch this again, please do your best to document your changes and try to resolve mysteries surrounding this code.
// I did what I could to document the parts I managed to understand, but there is still more truth to be unveiled.
//
// HOURS_WASTED_HERE_FLOOFSTATION = 10
// HOURS_WASTED_HERE_DELTAV = 1
namespace Content.Shared._Floof.OfferItem;
public abstract partial class SharedOfferItemSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly AlertsSystem _alertsSystem = default!;
[Dependency] private readonly CarryingSystem _carrying = default!;
[Dependency] private readonly PullingSystem _pulling = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<OfferItemComponent, AcceptOfferAlertEvent>(OnAcceptOffer);
SubscribeLocalEvent<OfferItemComponent, InteractUsingEvent>(OnInteractWithReceiver, before: [typeof(IngestionSystem)]);
SubscribeLocalEvent<OfferableVirtualItemComponent, BeforeRangedInteractEvent>(OnRangedInteractWithReceiver);
SubscribeLocalEvent<OfferItemComponent, MoveEvent>(OnMove);
SubscribeLocalEvent<BeingCarriedComponent, ItemTransferredEvent>(OnCarryTransfer);
SubscribeLocalEvent<PullableComponent, ItemTransferredEvent>(OnPulledTransfer);
InitializeInteractions();
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<OfferItemComponent, HandsComponent>();
while (query.MoveNext(out var uid, out var offerItem, out var hands))
{
// If the mob no longer holds an item in the original offering hand, clear offering mode
if (offerItem.Hand != null && !_hands.TryGetHeldItem((uid, hands), offerItem.Hand, out _))
{
if (offerItem.ReceivingFrom != null)
{
UnReceive(offerItem.ReceivingFrom.Value, offererComp: offerItem);
offerItem.IsInOfferMode = false;
Dirty(uid, offerItem);
}
else
UnOffer(uid, offerItem);
}
if (!offerItem.IsInReceiveMode)
{
_alertsSystem.ClearAlert(uid, offerItem.OfferAlert);
continue;
}
_alertsSystem.ShowAlert(uid, offerItem.OfferAlert);
}
}
#region Events
private void OnAcceptOffer(Entity<OfferItemComponent> ent, ref AcceptOfferAlertEvent args)
{
Receive((ent, ent.Comp));
}
private void OnInteractWithReceiver(Entity<OfferItemComponent> receiver, ref InteractUsingEvent args)
{
if (!_timing.IsFirstTimePredicted || _timing.ApplyingState || args.Handled)
return;
if (!TryComp<OfferItemComponent>(args.User, out var offererComponent))
return;
args.Handled = CreateOffer(receiver, (args.User, offererComponent));
}
private void OnRangedInteractWithReceiver(Entity<OfferableVirtualItemComponent> virtItem, ref BeforeRangedInteractEvent args)
{
// If the entity being offered is a virtual item, InteractUsing will not be raised
// because virtual items exclude themselves from being marked as used
// If this is the case, InteractHand will be raised instead, which we can use anyway because OfferItem.Item stores the offered item
//
// We also can't check Handled here because VirtualItemSystem handles it, ffs
// This won't lead you to accidentally offering someone your gun
//
// This is shitcode, this time my shitcode. My changes to the offering system allow you to transfer carrying and pulling,
// but in order to handle these, we need to be able to intercept interactions with virtual items.
//
// Ideally this code should be rewritten to:
// a) Have each different virtual item have a distinct component (e.g. CarryingVirtualItem) which would allow to distinguish them from the rest
// b) Not rely on the InteractionSystem.
// However, I'm not in the mood to do either. And I'm too deep into the rabbit hole of getting this shit to work.
if (!_timing.IsFirstTimePredicted || _timing.ApplyingState)
return;
var receiver = args.Target;
if (!TryComp<OfferItemComponent>(receiver, out var receiverComponent))
return;
var offerer = args.User;
if (!TryComp<OfferItemComponent>(offerer, out var offererComponent) || offererComponent.Item == null)
return;
// Since this is ranged, we must also check distance, because the interaction system wont check it for us in this case
if (!Transform(offerer).Coordinates.TryDistance(EntityManager, _transform, Transform(receiver.Value).Coordinates, out var dst)
|| dst > offererComponent.MaxOfferDistance)
return;
args.Handled = CreateOffer((receiver.Value, receiverComponent), (offerer, offererComponent));
}
private void OnMove(EntityUid uid, OfferItemComponent component, MoveEvent args)
{
if (_net.IsClient) // Client often mispredicts movement, we cant trust it here
return;
if (component.ReceivingFrom == null)
return;
if (_transform.InRange(args.NewPosition, Transform(component.ReceivingFrom.Value).Coordinates, component.MaxOfferDistance))
return;
UnOffer(uid, component);
}
private void OnCarryTransfer(Entity<BeingCarriedComponent> ent, ref ItemTransferredEvent args)
{
if (args.Handled
|| args.PassedItem == args.RealItem // Means the entity is transferred NOT via carrying
|| args.RealItem is not { Valid: true } carried
|| ent.Comp.Carrier is not { Valid: true } oldCarrier)
return;
_carrying.DropCarried(oldCarrier, ent);
args.Handled = _carrying.TryCarry(args.Target, carried);
}
private void OnPulledTransfer(Entity<PullableComponent> ent, ref ItemTransferredEvent args)
{
if (args.Handled
|| args.PassedItem == args.RealItem // Means the entity is transferred NOT via pulling
|| args.RealItem is not { Valid: true } pulled)
return;
_pulling.TryStopPull(pulled, ent);
args.Handled = _pulling.TryStartPull(args.Target, ent, null, ent.Comp);
}
#endregion
#region Offering / Recieving
/// <summary>
/// Attempts to create an offer. Expects offerer.Item to already be set to the offered item, offererComponent.InReceiveMode == true.
/// Will fail if offerer == receiver or if receiver already has a set TargetOrOfferer, and that person is not the current offerer
/// </summary>
private bool CreateOffer(Entity<OfferItemComponent> receiver, Entity<OfferItemComponent> offerer)
{
var offererComponent = offerer.Comp;
var receiverComponent = receiver.Comp;
if (offerer == receiver || receiverComponent.IsInReceiveMode || !offererComponent.IsInOfferMode)
return false;
if (offererComponent.IsInReceiveMode && offererComponent.ReceivingFrom != receiver)
return false;
receiverComponent.IsInReceiveMode = true;
receiverComponent.ReceivingFrom = offerer;
Dirty(receiver, receiverComponent);
offererComponent.ReceivingFrom = receiver; // TODO this is ee shitcode, may not be necessary?
offererComponent.IsInOfferMode = false;
Dirty(offerer, offererComponent);
if (offererComponent.Item == null)
return false;
// Sender popup (client-side only)
_popup.PopupClient(
Loc.GetString("offer-item-try-give",
("item", Identity.Entity(offererComponent.GetRealEntity(EntityManager), EntityManager)),
("target", Identity.Entity(receiver, EntityManager))),
offerer,
offerer);
// Receiver popup (server side only, not predicted because recipient != local player)
_popup.PopupEntity(
Loc.GetString("offer-item-try-give-target",
("user", Identity.Entity(receiverComponent.ReceivingFrom.Value, EntityManager)),
("item", Identity.Entity(offererComponent.GetRealEntity(EntityManager), EntityManager))),
offerer,
receiver,
Popups.PopupType.Medium);
return true;
}
/// <summary>
/// Resets the <see cref="OfferItemComponent"/> of the user and the target
/// </summary>
protected void UnOffer(EntityUid thisEntity, OfferItemComponent offererComp)
{
if (!TryComp<HandsComponent>(thisEntity, out var hands) || _hands.GetActiveHand((thisEntity, hands)) is null)
return;
if (offererComp.ReceivingFrom is { } otherEntity && TryComp<OfferItemComponent>(otherEntity, out var otherOfferer))
{
// So this tries to figure out which of these entities do what...
// if A.OfferItemComponent.Item != null, then A is currently offering an item to A.OfferItemComponent.TargetOrOfferer
// If it is null, then it is ONLY being offered an item TO.
if (offererComp.Item != null && _net.IsServer)
{
_popup.PopupEntity(
Loc.GetString("offer-item-no-give",
("item", Identity.Entity(offererComp.GetRealEntity(EntityManager), EntityManager)), // Floof - resolve virtual items
("target", Identity.Entity(otherEntity, EntityManager))),
thisEntity,
thisEntity);
_popup.PopupEntity(
Loc.GetString("offer-item-no-give-target",
("user", Identity.Entity(thisEntity, EntityManager)),
("item", Identity.Entity(offererComp.GetRealEntity(EntityManager), EntityManager))),
thisEntity,
otherEntity);
}
else if (otherOfferer.Item != null && _net.IsServer)
{
_popup.PopupEntity(
Loc.GetString("offer-item-no-give",
("item", Identity.Entity(otherOfferer.GetRealEntity(EntityManager), EntityManager)), // Floof - resolve virtual items
("target", Identity.Entity(thisEntity, EntityManager))),
otherEntity,
otherEntity);
_popup.PopupEntity(
Loc.GetString("offer-item-no-give-target",
("user", Identity.Entity(otherEntity, EntityManager)),
("item", Identity.Entity(otherOfferer.GetRealEntity(EntityManager), EntityManager))),
otherEntity,
thisEntity);
}
otherOfferer.IsInOfferMode = false;
otherOfferer.IsInReceiveMode = false;
otherOfferer.Hand = null;
otherOfferer.ReceivingFrom = null;
otherOfferer.Item = null;
Dirty(otherEntity, otherOfferer);
}
offererComp.IsInOfferMode = false;
offererComp.IsInReceiveMode = false;
offererComp.Hand = null;
offererComp.ReceivingFrom = null;
offererComp.Item = null;
Dirty(thisEntity, offererComp);
}
/// <summary>
/// Cancels the transfer of the item
/// </summary>
protected void UnReceive(EntityUid receiver, OfferItemComponent? receiverComp = null, OfferItemComponent? offererComp = null)
{
if (!Resolve(receiver, ref receiverComp)
|| receiverComp.ReceivingFrom is not {} offerer
|| !Resolve(offerer, ref offererComp))
return;
// Idk why this check is here
if (!TryComp<HandsComponent>(receiver, out var hands) || _hands.GetActiveHand((receiver, hands)) == null || receiverComp.ReceivingFrom == null)
return;
// If offererComp.Item != null, then they are actively offering to TargetOrOfferer
// Normally this method is called right after a transfer is done, but this part can be called from SetInOfferMode when the player presses F again to cancel an ongoing offer
if (offererComp.Item != null)
{
_popup.PopupClient(
Loc.GetString("offer-item-no-give",
("item", Identity.Entity(offererComp.GetRealEntity(EntityManager), EntityManager)), // Floof - resolve virtual items
("target", Identity.Entity(receiver, EntityManager))),
offerer,
offerer);
_popup.PopupEntity(
Loc.GetString("offer-item-no-give-target",
("user", Identity.Entity(receiverComp.ReceivingFrom.Value, EntityManager)), // Floof - resolve virtual items
("item", Identity.Entity(offererComp.GetRealEntity(EntityManager), EntityManager))),
offerer,
receiver);
}
if (!offererComp.IsInReceiveMode)
{
offererComp.ReceivingFrom = null;
receiverComp.ReceivingFrom = null;
}
offererComp.Item = null;
offererComp.Hand = null;
receiverComp.IsInReceiveMode = false;
Dirty(receiver, receiverComp);
}
/// <summary>
/// Accepting the offer and receive item
/// </summary>
public void Receive(Entity<OfferItemComponent?> receiver)
{
if (!_timing.IsFirstTimePredicted)
return;
if (!Resolve(receiver, ref receiver.Comp))
return;
if (!TryComp<OfferItemComponent>(receiver.Comp.ReceivingFrom, out var offererComponent) ||
offererComponent.Hand == null ||
receiver.Comp.ReceivingFrom is not {} sender ||
!TryComp<HandsComponent>(receiver, out var hands))
return;
if (offererComponent.Item != null)
{
// Floof - check if there's something else handling it first
var realItem = offererComponent.GetRealEntity(EntityManager);
if (!TryHandleExtendedTransfer(sender, receiver, offererComponent.Item.Value, realItem)
&& !_hands.TryPickup(receiver, offererComponent.Item.Value, handsComp: hands))
{
_popup.PopupEntity(Loc.GetString("offer-item-full-hand"), receiver, receiver);
return;
}
_popup.PopupEntity(
Loc.GetString("offer-item-give",
("item", Identity.Entity(realItem, EntityManager)), // FLoof - resolve virtual items
("target", Identity.Entity(receiver, EntityManager))),
sender,
sender);
_popup.PopupEntity(
Loc.GetString("offer-item-give-other",
("user", Identity.Entity(receiver.Comp.ReceivingFrom.Value, EntityManager)),
("item", Identity.Entity(realItem, EntityManager)), // FLoof - resolve virtual items
("target", Identity.Entity(receiver, EntityManager))),
sender,
Filter.PvsExcept(sender, entityManager: EntityManager),
true);
}
offererComponent.Item = null;
UnReceive(receiver, receiver.Comp, offererComponent);
}
#endregion
/// <summary>
/// Returns true if <see cref="OfferItemComponent.IsInOfferMode"/> = true
/// </summary>
protected bool IsInOfferMode(Entity<OfferItemComponent?> ent)
{
return Resolve(ent, ref ent.Comp, false) && ent.Comp.IsInOfferMode;
}
private bool TryHandleExtendedTransfer(EntityUid user, EntityUid target, EntityUid offeredItem, EntityUid realItem)
{
var ev = new ItemTransferredEvent
{
User = user,
Target = target,
PassedItem = offeredItem,
RealItem = realItem,
};
RaiseLocalEvent(realItem, ref ev);
return ev.Handled;
}
}
/// <summary>
/// Raised on the entity that was transferred via item offering.
/// </summary>
[ByRefEvent]
public sealed class ItemTransferredEvent : HandledEntityEventArgs
{
public EntityUid User;
public EntityUid Target;
/// <summary>
/// The actual item being passed around. Can be a virtual item.
/// </summary>
public EntityUid PassedItem;
/// <summary>
/// If <see cref="PassedItem"/> is a virtual item, this field contains the real item that was transferred.
/// </summary>
public EntityUid? RealItem;
}
@@ -0,0 +1,66 @@
using Robust.Shared.GameStates;
namespace Content.Shared._Impstation.Clothing;
/// <summary>
/// Adds examine text to the entity that wears item, for making things obvious.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(WearerGetsExamineTextSystem))]
public sealed partial class WearerGetsExamineTextComponent : Component
{
/// <summary>
/// The LocId that specifies what category of object this is.
/// i.e. "pin" or "scarf"
/// Should be redefined on a per-category basis, naturally.
/// </summary>
[DataField("thing")]
public LocId Category = "obvious-thing-default";
/// <summary>
/// The LocId that specifies what member of the category this is.
/// i.e. "lesbian pride"
/// Can be used to define text colors that are copied to all things
/// which share this specifier (i.e. the other items of the same pride).
/// (And summarily, makes accessibility-based changes for these colors a cinch.)
/// Should be defined by each thing that has this component.
/// </summary>
[DataField("thingType")]
public LocId Specifier = "obvious-type-default";
/// <summary>
/// The LocId that will be added to any wearing entity's examination.
/// Typically only needs redefining on a per-category basis,
/// but items that should have totally-unique obvious text can simply specify them here.
/// </summary>
[DataField("examineText", required: true)]
public LocId ExamineOnWearer = "obvious-desc-default";
/// <summary>
/// Reference to the entity wearing this clothing.
/// </summary>
[DataField, AutoNetworkedField]
public EntityUid? Wearer;
/// <summary>
/// The string that is attached to this item's ExamineOnWearer.
/// Typically doesn't need to be redefined.
/// </summary>
[DataField]
public LocId PrefixExamineOnWearer = "obvious-prefix-wearing";
/// <summary>
/// If true, an entity with this item in any slot (i.e. in pockets) will gain the examine text,
/// instead of when just equipped as clothing.
/// Should be used sparingly only when truly appropriate; this is effectively a half-measure for lack of a special pin slot.
/// </summary>
[DataField]
public bool PocketEvident;
/// <summary>
/// If true, the entity's description will inform examiners what others will see on the wearer (before they equip it).
/// If the item is contraband, the item will also warn that displaying it may cause undue attention.
/// Keep this false for good-natured jokes (i.e. the pride cloaks having funny, non-pride names)
/// </summary>
[DataField]
public bool WarnExamine = true;
}
@@ -0,0 +1,111 @@
using Content.Shared.Clothing.Components;
using Content.Shared.Examine;
using Content.Shared.IdentityManagement;
using Content.Shared.Inventory.Events;
using Content.Shared.Contraband;
using Content.Shared._Impstation.Examine;
using System.Text;
namespace Content.Shared._Impstation.Clothing;
/// <summary>
/// Adds examine text to the entity that wears item, for making things obvious.
/// </summary>
public sealed class WearerGetsExamineTextSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WearerGetsExamineTextComponent, GotEquippedEvent>(OnEquipped);
SubscribeLocalEvent<WearerGetsExamineTextComponent, GotUnequippedEvent>(OnUnequipped);
SubscribeLocalEvent<WearerGetsExamineTextComponent, ExaminedEvent>(OnExamine);
}
private void OnEquipped(Entity<WearerGetsExamineTextComponent> entity, ref GotEquippedEvent args)
{
if (!TryComp(entity, out ClothingComponent? clothing))
return;
var isCorrectSlot = (clothing.Slots & args.SlotFlags) != Inventory.SlotFlags.NONE;
if (!entity.Comp.PocketEvident) //if it can't be evident in our pockets
{
// Make sure the clothing item was equipped to the right slot, and not just held in a hand.
if (!isCorrectSlot)
return;
}
entity.Comp.Wearer = args.Equipee;
Dirty(entity);
//GIVE THEM INSPECT TEXT
var obviousExamine = EnsureComp<ExtraExamineTextComponent>(args.Equipee);
obviousExamine.Lines.TryAdd(entity.Owner, //using try so that we don't cause an error if we move something from slot to slot
ConstructExamineText(entity, !isCorrectSlot, args.Equipee));
}
private string ConstructExamineText(Entity<WearerGetsExamineTextComponent> entity, bool prefixFallback, EntityUid affecting)
{
//parameters (these are the same between both constructions)
var user = Identity.Entity(affecting, EntityManager);
var nomen = Identity.Name(affecting, EntityManager);
var thing = Loc.GetString(entity.Comp.Category);
var type = Loc.GetString(entity.Comp.Specifier);
var stringSpec = entity.Comp.Specifier.ToString();
var shortType = stringSpec.Substring(stringSpec.LastIndexOf('-')); // necessary for working with colored text...
var prefix = Loc.GetString(prefixFallback ? "obvious-prefix-default" : entity.Comp.PrefixExamineOnWearer, // uses a different prefix if worn / displayed
("user", user),
("name", nomen),
("thing", thing),
("type", type));
var suffix = Loc.GetString(entity.Comp.ExamineOnWearer,
("user", user),
("name", nomen),
("thing", thing),
("type", type),
("short-type", shortType));
return prefix + " " + suffix;
}
private void OnUnequipped(Entity<WearerGetsExamineTextComponent> entity, ref GotUnequippedEvent args)
{
if (entity.Comp.Wearer is not { } wearer)
return;
if (TryComp(wearer, out ExtraExamineTextComponent? obviousExamine))
{
obviousExamine.Lines.Remove(entity.Owner);
}
entity.Comp.Wearer = null;
Dirty(entity);
}
private void OnExamine(Entity<WearerGetsExamineTextComponent> entity, ref ExaminedEvent args)
{
var currentlyWorn = entity.Comp.Wearer != null;
var outString = new StringBuilder(Loc.GetString(currentlyWorn ? "obvious-on-item-currently" : "obvious-on-item",
("used", Loc.GetString(entity.Comp.PocketEvident ? "obvious-reveal-pockets" : "obvious-reveal-default")),
("thing", entity.Comp.Category),
("me", Identity.Entity(entity, EntityManager))));
if (entity.Comp.WarnExamine)
{
if (!currentlyWorn && TryComp(entity, out ContrabandComponent? contra)) // if the item's contra and we're not wearing it yet
{
var contraLocId = "obvious-on-item-contra-" + contra.Severity; // apply additional text if the item is contraband to note that displaying it might be really bad
if (Loc.HasString(contraLocId)) // saves us the trouble of making a switch block for this
outString.Append(" " + Loc.GetString(contraLocId));
}
var affecting = currentlyWorn ? entity.Comp.Wearer.GetValueOrDefault() : args.Examiner;
var testOut = ConstructExamineText(entity, false, affecting);
outString.Append("\n" + Loc.GetString("obvious-on-item-for-others",
("will", currentlyWorn ? "can" : "will"), // i love hardcoding strings it's my favorite thing ever
("output", testOut)));
}
args.PushMarkup(outString.ToString());
}
}
@@ -0,0 +1,40 @@
using Robust.Shared.GameStates;
namespace Content.Shared._Impstation.Examine;
[RegisterComponent, NetworkedComponent]
public sealed partial class DetailedInspectComponent : Component
{
[DataField]
public LocId VerbText = "verbs-detailed-inspect";
[DataField]
public LocId VerbMessage = "verbs-detailed-inspect-message";
[DataField(required: true)]
public List<LocId> ExamineText;
/// <summary>
/// Whether or not the entries in ExamineText are separated by linebreaks.
/// </summary>
[DataField]
public bool LineBreak = true;
/// <summary>
/// Whether or not the entries in ExamineText are preceded by ticks.
/// </summary>
[DataField]
public bool TickEntries = false;
/// <summary>
/// Whether or not entries in the list are numbered.
/// </summary>
[DataField]
public bool NumberedEntries = false;
/// <summary>
/// Rooted directory of the icon for the verb.
/// </summary>
[DataField]
public string Icon = "/Textures/Interface/VerbIcons/dot.svg.192dpi.png";
}
@@ -0,0 +1,50 @@
using Content.Shared.Examine;
using Content.Shared.Verbs;
using Robust.Shared.Network;
using Robust.Shared.Utility;
namespace Content.Shared._Impstation.Examine;
public sealed partial class DetailedInspectSystem : EntitySystem
{
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly ExamineSystemShared _examine = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DetailedInspectComponent, GetVerbsEvent<ExamineVerb>>(OnGetVerb);
}
public void OnGetVerb(Entity<DetailedInspectComponent> ent, ref GetVerbsEvent<ExamineVerb> args)
{
if (!args.CanInteract || !args.CanAccess || !_net.IsServer)
return;
var msg = new FormattedMessage();
var numberedIndex = 1;
foreach (var locId in ent.Comp.ExamineText)
{
if (ent.Comp.TickEntries)
msg.AddMarkupOrThrow("- ");
if (ent.Comp.NumberedEntries)
{
msg.AddMarkupOrThrow($"{numberedIndex}. ");
numberedIndex++;
}
msg.AddMarkupOrThrow(Loc.GetString(locId));
if (ent.Comp.LineBreak)
msg.PushNewline();
else
msg.AddMarkupOrThrow(" ");
}
_examine.AddDetailedExamineVerb(args, ent.Comp, msg, Loc.GetString(ent.Comp.VerbText), ent.Comp.Icon, Loc.GetString(ent.Comp.VerbMessage));
}
}
@@ -0,0 +1,24 @@
using Robust.Shared.GameStates;
using Content.Shared._Impstation.Clothing;
namespace Content.Shared._Impstation.Examine;
/// <summary>
/// Adds examine text to the entity, intentionally "obvious details".
/// Like, that's it. It's basic -- all it does is add the lines to the attached entity.
/// This is particularly used for assigning players unique examine text.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(ExtraExamineTextSystem), typeof(WearerGetsExamineTextSystem))]
public sealed partial class ExtraExamineTextComponent : Component
{
/// <summary>
/// The LocIds that will be added to the attached entity's examination.
///
/// The key is the source of the line, and the value is the text
/// (built by the component that creates this one).
/// </summary>
[DataField, AutoNetworkedField]
public Dictionary<EntityUid, LocId> Lines { get; set; } = new();
}
@@ -0,0 +1,33 @@
using Content.Shared.Examine;
using Content.Shared.IdentityManagement;
namespace Content.Shared._Impstation.Examine;
/// <summary>
/// Adds examine text to the entity, intentionally "obvious details".
/// Like, that's it. It's basic -- all it does is add the line to the attached entity.
/// This is particularly used for assigning players unique examine text.
/// </summary>
public sealed class ExtraExamineTextSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ExtraExamineTextComponent, ExaminedEvent>(OnExamine);
}
private void OnExamine(Entity<ExtraExamineTextComponent> entity, ref ExaminedEvent args)
{
if (entity.Comp.Lines.Count == 0)
{
RemCompDeferred<ExtraExamineTextComponent>(entity); // no more need for me!
return;
}
foreach (var l in entity.Comp.Lines)
{
args.PushMarkup(l.Value);
}
}
}
@@ -0,0 +1,8 @@
namespace Content.Shared._Starlight.Flash.Components;
[RegisterComponent]
public sealed partial class FlashModifierComponent : Component
{
[DataField]
public float Modifier = 1f;
}
@@ -0,0 +1,51 @@
namespace Content.Shared.Humanoid;
public static class EyeColor
{
public const float ShadekinBrightness = 0.251f;
public static bool VerifyShadekin(Color color)
{
var colorHsv = Color.ToHsv(color);
if (colorHsv.Z > ShadekinBrightness)
return false;
return true;
}
public static Color MakeShadekinValid(Color color)
{
var hsv = Color.ToHsv(color);
hsv.Z = Math.Clamp(hsv.Z, 0, ShadekinBrightness);
return Color.FromHsv(hsv);
}
public static bool VerifyEyeColor(HumanoidEyeColor type, Color color)
{
return type switch
{
HumanoidEyeColor.Shadekin => VerifyShadekin(color),
_ => false,
};
}
public static Color ValidEyeColor(HumanoidEyeColor type, Color color)
{
return type switch
{
HumanoidEyeColor.Shadekin => MakeShadekinValid(color),
_ => color
};
}
}
public enum HumanoidEyeColor : byte
{
Shadekin,
}
[ByRefEvent]
public record struct EyeColorInitEvent();
@@ -0,0 +1,45 @@
using Content.Shared.Alert;
using Content.Shared.FixedPoint;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared._Starlight;
#region Shadekin
[RegisterComponent, NetworkedComponent, AutoGenerateComponentPause, AutoGenerateComponentState]
public sealed partial class ShadekinComponent : Component
{
[DataField]
public ProtoId<AlertPrototype> ShadekinAlert = "Shadekin";
[ViewVariables(VVAccess.ReadOnly), AutoPausedField]
public TimeSpan NextUpdate = TimeSpan.Zero;
[DataField]
public TimeSpan UpdateCooldown = TimeSpan.FromSeconds(1f);
[AutoNetworkedField, ViewVariables]
public ShadekinState CurrentState { get; set; } = ShadekinState.Dark;
[DataField("thresholds", required: true)]
public SortedDictionary<FixedPoint2, ShadekinState> Thresholds = new();
/// <summary>
/// whether to flicker lights or not. default on
/// </summary>
[DataField] public bool DoLightFlicker = true;
}
[Serializable, NetSerializable]
public enum ShadekinState : byte
{
Invalid = 0,
Dark = 1,
Low = 2,
Annoying = 3,
High = 4,
Extreme = 5
}
#endregion
@@ -0,0 +1,9 @@
- files: ["beep_500.ogg"]
license: "CC0-1.0"
copyright: "Synthesized in Audacity by BasedUser."
source: "https://github.com/ekrixi-14/ekrixi"
- files: ["whirr1.ogg", "whirr2.ogg", "whirr3.ogg"]
license: "CC0-1.0"
copyright: "Taken from source, spectrally modified and clipped"
source: "https://freesound.org/people/sad3d/sounds/500168/"
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,29 @@
- files: ["wurble.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/wurble.ogg"
- files: ["mar.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/mar.ogg"
- files: ["scream_f1.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken and remixed from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/scream_f1.ogg"
- files: ["scream_f2.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken and remixed from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/scream_f2.ogg"
- files: ["scream_m1.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken and remixed from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/scream_m1.ogg"
- files: ["scream_m2.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Taken and remixed from CHOMPStation"
source: "https://github.com/CHOMPStation2/CHOMPStation2/blob/e846f4f73d14875a390ede039a11e4b9b699f420/sound/voice/scream_f2.ogg"
Binary file not shown.
Binary file not shown.
+16
View File
@@ -332,5 +332,21 @@ Entries:
id: 36
time: '2026-06-16T20:02:18.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6006
- author: einknusprigestoast
changes:
- message: Changed SRT loadouts
type: Tweak
- message: Added the eviscerator, a ERT-/SRT-issued heavy plasma rifle.
type: Add
id: 37
time: '2026-07-13T13:44:06.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6233
- author: einknusprigestoast
changes:
- message: The white dragon has been spotted in the sector.
type: Add
id: 38
time: '2026-07-19T16:18:47.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6317
Name: DeltaVAdmin
Order: 5
+474 -448
View File
@@ -1,452 +1,4 @@
Entries:
- author: kotobdev
changes:
- message: Flashlights will now always point towards your cursor in combat mode.
type: Add
id: 2034
time: '2026-01-08T17:11:25.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5163
- author: ShepardToTheStars
changes:
- message: Redrock spawns a bit further out until we can figure out why its spawning
inside the station.
type: Tweak
id: 2035
time: '2026-01-08T20:53:31.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5166
- author: PureBreadBagel
changes:
- message: You are now able to craft the makeshift and forged varient of the omnitool!
type: Fix
- message: The makeshift/forged varient of the omnitool should no longer display
"verb-categories-switch" in its right click menu.
type: Fix
id: 2036
time: '2026-01-09T16:34:26.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5165
- author: MilonPL
changes:
- message: Picking senior PDAs in the loadout will now change your job name accordingly
once again.
type: Fix
id: 2037
time: '2026-01-10T16:48:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5176
- author: Eternally-Confused
changes:
- message: The announcement for the Spare Captain's ID no longer references crimes
that don't exist
type: Fix
id: 2038
time: '2026-01-10T21:42:58.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5177
- author: Eternally-Confused
changes:
- message: Feroxi nukies now recieve actual syndicate survival boxes.
type: Fix
id: 2039
time: '2026-01-10T21:43:51.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5179
- author: FaintSpeaker
changes:
- message: Fix for one error possibly causing replays to fail to load. Continue
to report any broken replays after this fix!
type: Fix
id: 2040
time: '2026-01-10T21:44:55.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5173
- author: snowywinters
changes:
- message: The station AI is now better integrated into the station allowing use
of fabs and substations/SMES
type: Add
id: 2041
time: '2026-01-10T21:58:12.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5132
- author: FaintSpeaker
changes:
- message: Adv. Cleaning Cyborg Module now regenerates Space Cleaner.
type: Add
id: 2042
time: '2026-01-10T22:07:44.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5155
- author: ShepardToTheStars, Toby222
changes:
- message: Fixed feroxi paramedic and goliath hardsuit helmet sprites displaying
the incorrect sprite.
type: Fix
id: 2043
time: '2026-01-10T22:07:30.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5161
- author: keekee38
changes:
- message: Increased minimum player count for nukies to 20 ready and 40 total players.
type: Tweak
id: 2044
time: '2026-01-10T23:06:04.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5159
- author: MilonPL
changes:
- message: Fixed emergency jaws of life not draining their battery when prying doors.
type: Fix
id: 2045
time: '2026-01-11T15:34:44.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5189
- author: ShepardToTheStars
changes:
- message: Crawling or being knocked down no longer nerfs your melee damage by 75%.
You will do the normal amount of melee damage now.
type: Tweak
id: 2046
time: '2026-01-11T15:38:24.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5182
- author: ShepardToTheStars
changes:
- message: The spare ID will always unlock 15 seconds after nukies declare war,
even if there is a captain.
type: Tweak
id: 2047
time: '2026-01-11T15:40:02.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5104
- author: Pharaz4
changes:
- message: Added Skia to guidebook.
type: Add
- message: Fixed some typos and a page on guidebook.
type: Fix
id: 2048
time: '2026-01-11T16:27:06.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5178
- author: Minerva
changes:
- message: Crash carts can now be ordered from Logistics under the Medical category.
type: Add
id: 2049
time: '2026-01-11T16:43:30.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5190
- author: DisposableCrewmember42
changes:
- message: The revenant can use its Haunt ability again
type: Fix
id: 2050
time: '2026-01-11T19:48:58.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5124
- author: DisposableCrewmember42
changes:
- message: The Revenant can no longer be killed by spiking your own water bottle.
type: Fix
id: 2051
time: '2026-01-11T19:57:38.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5125
- author: Apachito
changes:
- message: Moved the craftable armor to the clothing tab in the crafting menu
type: Tweak
- message: Reduced firerate on the forged smg from 5 to 4.5
type: Tweak
- message: Made improvised ammo do 75% damage compared to their normal counterparts
type: Tweak
id: 2052
time: '2026-01-11T22:08:13.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5129
- author: Unkn0wnGh0st333
changes:
- message: Gulp Emote from Goob has been added... gulp...
type: Add
id: 2053
time: '2026-01-12T04:42:07.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5033
- author: Velcroboy
changes:
- message: Tanks of ammonia are now purchasable from logi for mixing more space
cleaner or making the station stinky
type: Add
id: 2054
time: '2026-01-13T05:00:57.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5167
- author: Pharaz4
changes:
- message: Syndicate Assault, Medical, and Saboteur borgs now get names.
type: Add
- message: Fixed SRN Saboteur borg not being able to fit Engineering module
type: Fix
id: 2055
time: '2026-01-14T13:23:22.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5197
- author: MilonPL
changes:
- message: Added a dynamic tip system that shows contextual tips to players based
on their job, playtime, and more.
type: Add
- message: Tips can be disabled or reset in the Options menu under DeltaV.
type: Add
id: 2056
time: '2026-01-14T20:23:40.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5199
- author: Velcroboy
changes:
- message: Fixed bomb and effigy targets being on grids off the station sometimes.
type: Fix
id: 2057
time: '2026-01-15T07:29:44.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5213
- author: Pharaz4
changes:
- message: Hard hats are now protective!
type: Tweak
id: 2058
time: '2026-01-15T15:44:57.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5175
- author: Halo3moth
changes:
- message: The hos locker will now spawn with a briefcase that allows them to pick
between sidearms.
type: Add
- message: The energy magnum now also works for the hos steal objective.
type: Tweak
- message: Energy magnum standard bolt from 20 heat to 24 and magnum bolt from 30
heat to 24 heat and 11 pierce.
type: Tweak
id: 2059
time: '2026-01-16T17:46:17.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5203
- author: mnva0
changes:
- message: Ovinia now start with a emergency survival box.
type: Fix
id: 2060
time: '2026-01-16T17:55:22.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5207
- author: Halo3moth
changes:
- message: Re-added the graytide stamp to maints lockers.
type: Add
- message: Tweak some of the spawn rates for meme items in maints lockers.
type: Tweak
id: 2061
time: '2026-01-16T17:58:01.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5221
- author: Pharaz4
changes:
- message: Fixed extra hardsuit that spawned in Suit storage lockers.
type: Fix
- message: Fixed free Epistemics access for HoP in pTech.
type: Fix
id: 2062
time: '2026-01-16T17:59:12.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5201
- author: BarryNorfolk
changes:
- message: Added new mapping command 'togglenetworklinks'
type: Add
id: 2063
time: '2026-01-16T18:09:53.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5188
- author: Halo3moth
changes:
- message: Devils will now role 2.5 times more often.
type: Tweak
id: 2064
time: '2026-01-16T18:13:00.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5225
- author: EmberAstra
changes:
- message: Added the microwave emitter! Epistemics has a radiation gun to shoot
artifacts with now!
type: Add
id: 2065
time: '2026-01-16T18:19:04.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5205
- author: DisposableCrewmember42
changes:
- message: Lord Singuloth rises.
type: Tweak
id: 2066
time: '2026-01-16T18:26:06.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5209
- author: BunglesnortBoss
changes:
- message: Made AI Nanites a good option. Heals 50 HP with a shorter cooldown
type: Tweak
id: 2067
time: '2026-01-16T18:27:22.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5210
- author: pootslap
changes:
- message: Carpy has acquired a fancy new pen and stamp and is ready to dispense
legal advice.
type: Tweak
- message: Removed the duplicate chaplain stamp from the listening post
type: Fix
id: 2068
time: '2026-01-16T18:29:14.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5169
- author: cmorley191
changes:
- message: Harpies are now reliably more sensitive to pollutant gases than other
species. For example, 0.4% of CO2 will make harpies start gasping, while humans
are okay up to 1.1% CO2
type: Add
id: 2069
time: '2026-01-16T18:32:20.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5158
- author: ShepardToTheStars
changes:
- message: Added CentComm Shipyard to order free ships with CentComm access.
type: Add
id: 2070
time: '2026-01-16T18:37:33.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5172
- author: EmberAstra
changes:
- message: Made the Engineering Void Suit printable!
type: Tweak
id: 2071
time: '2026-01-16T18:41:11.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5222
- author: cmorley191
changes:
- message: The Oracle will no longer request items that are "very" far away from
being researched.
type: Tweak
id: 2072
time: '2026-01-16T18:58:51.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/4430
- author: Proxysseia
changes:
- message: Prison Knives no longer spawn in Prison Lockers
type: Remove
id: 2073
time: '2026-01-16T18:59:31.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/4934
- author: Toby222
changes:
- message: Removed footprint prediction (for now)
type: Remove
id: 2074
time: '2026-01-16T19:07:45.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5224
- author: Velcroboy
changes:
- message: Prisoners can find dull bread knives in the ChefVend.
type: Tweak
id: 2075
time: '2026-01-17T21:13:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5234
- author: Halo3moth
changes:
- message: The T1 armored vest (slim) can now once again be picked in security loadouts.
type: Add
id: 2076
time: '2026-01-17T21:36:45.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5220
- author: biddygelson
changes:
- message: 'Academy: added anti-meteor zones and anti-anomaly zone, AI restoration
console in Mystagogue, Robotics Console in robo, fishing hole added to park,
materials is cargo at roundstart.'
type: Add
- message: 'Academy: station starts with distro and waste enabled, spare atmos chambers
start as vacuums, split artifacts'' APCs for power management, botany has more
trays and is slightly larger, department-front holopads in the department.'
type: Tweak
id: 2077
time: '2026-01-18T01:54:56.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5130
- author: DisposableCrewmember42
changes:
- message: You can no longer drink the deep fryer.
type: Fix
id: 2078
time: '2026-01-18T04:40:48.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5238
- author: snowywinters
changes:
- message: Reinforced cameras can now be built! They have additional HP and are
more resistant to explosions and meteors.
type: Add
- message: The AI has its own section in the security cameras console.
type: Add
id: 2079
time: '2026-01-18T17:18:45.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5027
- author: Dorragon
changes:
- message: Ready Manifest added to the lobby
type: Add
id: 2080
time: '2026-01-18T18:47:07.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5187
- author: MilonPL
changes:
- message: Added a new traits system, supporting conditions and new effects. Make
sure to check out the Traits tab in the character editor!
type: Add
- message: All character traits have been reset.
type: Remove
id: 2081
time: '2026-01-20T11:49:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5208
- author: pootslap
changes:
- message: You can now examine character descriptions from much further away.
type: Tweak
id: 2082
time: '2026-01-20T11:49:48.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5219
- author: Eternally-Confused
changes:
- message: (TEST MERGE) Space pens now contain a chemical called Stabilizine instead
of Leporazine, which is better at stabilizing body temperature.
type: Tweak
- message: Avali no longer die from space pens.
type: Tweak
id: 2083
time: '2026-01-20T21:15:21.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5181
- author: turtlemutt
changes:
- message: Added more names for ghost role spawns.
type: Add
id: 2084
time: '2026-01-21T05:17:05.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5254
- author: Cepelinas1
changes:
- message: Logistics Officers can now use the shipyard to buy shuttles. No need
to beg Captain to buy it anymore!
type: Add
id: 2085
time: '2026-01-21T05:52:10.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5251
- author: Colin-Tel
changes:
- message: Eked the Anglish tung tie. In other words, added a trait that lets you
talk like an Anglo Saxon with over 1,100 word replacements.
type: Add
id: 2086
time: '2026-01-21T09:37:07.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/4092
- author: ShepardToTheStars
changes:
- message: The ninja is now revealed with hit with attacks, projectiles, explosions,
and grenades that do damage.
type: Tweak
- message: The ninja is now revealed with hit with attacks, projectiles, explosions,
and grenades that do damage.
type: Fix
id: 2087
time: '2026-01-21T14:18:56.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5217
- author: Toby222
changes:
- message: FTL times have been adjusted. Startup is shorter, travel is longer.
type: Tweak
- message: The FTL startup sound now lines up with the duration of startup again!!!
type: Fix
id: 2088
time: '2026-01-21T14:50:49.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5257
- author: ShepardToTheStars, foxcumberland
changes:
- message: Added fashionable longcoats for command, security, and crew. Find them
@@ -4339,4 +3891,478 @@
id: 2534
time: '2026-07-07T18:40:15.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6055
- author: jessiscah23
changes:
- message: Nanotrasen has fixed issues with salvage magnet calibration. Ore seams
can now be found on asteroid pulls!
type: Fix
id: 2535
time: '2026-07-09T01:24:45.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5973
- author: rebe83
changes:
- message: The syndicate saboteur cyborg no longer comes with weapons or an advanced
tool module. Cybersun stocks are down 13%.
type: Tweak
id: 2536
time: '2026-07-09T03:53:55.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6080
- author: keekee38
changes:
- message: after years of testing, NT managed to make more bullets fit into the
magnum cartridge boxes
type: Tweak
id: 2537
time: '2026-07-09T04:42:44.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6226
- author: rebe83
changes:
- message: Revenant can be grinded... ground...grounded up in a grinder without
salt to be killed WITHOUT exploding!
type: Tweak
- message: Revenant stasis time increased from 60 seconds to 100 seconds.
type: Tweak
- message: Skia takes a bit less damage from light sources.
type: Tweak
id: 2538
time: '2026-07-09T11:38:49.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5981
- author: Eternally-Confused
changes:
- message: The "Sentencing" and "Crime Modifiers" sections of Space Law have been
added to the in-game guidebook.
type: Fix
id: 2539
time: '2026-07-09T13:29:07.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6223
- author: Halo3moth
changes:
- message: Antagonist Guidelines have been updated please re-review them!
type: Tweak
id: 2540
time: '2026-07-09T18:03:20.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5929
- author: CarolCuchara
changes:
- message: Secure cabinets now need to be unlocked to be able to insert items!
type: Tweak
id: 2541
time: '2026-07-10T13:59:29.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6269
- author: Radezolid
changes:
- message: Seismic charges cost increased from 1250 mining points to 6250 mining
points.
type: Tweak
id: 2542
time: '2026-07-10T14:05:18.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6245
- author: ShepardToTheStars
changes:
- message: Advanced cleaning is now a T3 civilian services research.
type: Tweak
id: 2543
time: '2026-07-10T15:03:13.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6271
- author: ShepardToTheStars
changes:
- message: You can no longer see your own health bar with the medical hud (or similar
eyewear).
type: Tweak
id: 2544
time: '2026-07-10T17:22:38.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6241
- author: ShepardToTheStars
changes:
- message: New death implanters have been added to the syndicate uplink for those
to get the objective to die a glorious death - the true death implanter (free),
death acidifier implanter (free), and microbomb implanter (2TC). Choose wisely
because you only get one.
type: Add
id: 2545
time: '2026-07-10T19:58:17.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6221
- author: CheddaCheez
changes:
- message: Rodentia can now have whiskers and ears at the same time. Cheek fluff
too.
type: Tweak
id: 2546
time: '2026-07-10T20:08:32.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6273
- author: stormyatt
changes:
- message: Added welding mask and multitool to utility belt for MG and salvagers.
type: Add
- message: Removed network configurator from utility belt for MG and salvagers.
type: Remove
id: 2547
time: '2026-07-10T20:20:09.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6217
- author: ArionGekkota
changes:
- message: Allulalo can now fit inside bags!
type: Add
id: 2548
time: '2026-07-10T20:21:42.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6248
- author: Radezolid
changes:
- message: The LO's knuckledusters are back in, get them at your closest Logistics
Officer's locker.
type: Tweak
id: 2549
time: '2026-07-11T08:29:20.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6243
- author: Radezolid
changes:
- message: Engineering tool belts now come with a nanite applicator.
type: Tweak
id: 2550
time: '2026-07-11T16:09:23.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6261
- author: ollyoaner
changes:
- message: "Slime people can now add elf ear customization markings! \U0001F9DD"
type: Add
id: 2551
time: '2026-07-11T16:30:08.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6265
- author: rebe83
changes:
- message: Ion damage has been removed.
type: Remove
id: 2552
time: '2026-07-11T16:34:56.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5960
- author: rebe83, mousesweater
changes:
- message: Command members now have learner PAIs in their locker ready to absorb
knowledge!
type: Add
id: 2553
time: '2026-07-11T17:25:07.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5924
- author: Coryler
changes:
- message: Avali Preened Feather Color are now correct again
type: Fix
id: 2554
time: '2026-07-13T13:32:05.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6285
- author: pootslap
changes:
- message: Starlight forged weapons/armour/ammo are no longer craftable.
type: Remove
id: 2555
time: '2026-07-13T13:46:25.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6250
- author: ArionGekkota
changes:
- message: Added the small arms mining kit to the mining voucher. It contains a
crusher dagger and mining drill!
type: Add
id: 2556
time: '2026-07-13T13:51:12.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6260
- author: jessiscah23
changes:
- message: Due to the growing influence of the Cargo Pilots' Employee Advocacy Group,
cargo telepads are no longer available to be researched.
type: Remove
id: 2557
time: '2026-07-13T14:24:25.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6266
- author: Velitation
changes:
- message: Added 2 new outfits and a mantle to the mime's loadout. The outfits can
also be printed out at a uniform printer.
type: Add
id: 2558
time: '2026-07-13T16:16:20.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6264
- author: ShepardToTheStars
changes:
- message: Derelict borgs no longer have access to heads' rooms.
type: Fix
id: 2559
time: '2026-07-13T17:38:08.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6284
- author: Coryler
changes:
- message: Character height should be correctly applied for clones and paradox clones.
type: Fix
id: 2560
time: '2026-07-13T19:58:26.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6205
- author: ShepardToTheStars
changes:
- message: Objects animated by glimmer, revenants, or magic cannot be turned into
zombies anymore.
type: Fix
id: 2561
time: '2026-07-13T20:36:52.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6291
- author: ShepardToTheStars
changes:
- message: Xenoborg ID chip slots are no longer compatible with crew ID chips or
IDs.
type: Tweak
- message: Only the Xenoborg Mothership Core can talk over binary. All xenoborgs
can still listen.
type: Tweak
- message: Xenoborgs now have EMP resistant batteries and will only take drain around
40% of battery.
type: Tweak
- message: Xenoborgs will only be disabled for 6 seconds when hit by an EMP, instead
of 60 seconds.
type: Tweak
- message: The Xenoborg mothership core now has a magnet for materials.
type: Tweak
- message: The Xenoborg silicon storage square now has a toggleable magnet.
type: Fix
id: 2562
time: '2026-07-13T21:26:01.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6278
- author: Cepelinas1
changes:
- message: Certain fauna, like space dragons or mice can now see in the dark!
type: Add
- message: Dragons can now smell blood.
type: Add
id: 2563
time: '2026-07-14T01:38:28.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5902
- author: Velitation
changes:
- message: Mime PDAs once again start with the NanoTask, NoteKeeper, and NanoChat
apps.
type: Tweak
id: 2564
time: '2026-07-15T00:43:20.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6252
- author: ShepardToTheStars
changes:
- message: The airlock access override now breaks accesses on the door. You can
see if accesses on doors have been broken with the Diagnostic HUD.
type: Tweak
- message: Added access configurators to engineer lockers, engineering techfab,
and the EngiVend. Engineers are now allowed to repair access around the station!
type: Add
- message: The AI and engineering borgs can now see if a door's accesses have been
modified.
type: Add
id: 2565
time: '2026-07-15T01:58:05.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6263
- author: MantasDab360
changes:
- message: Wanted Fugitive paper is no longer clustered.
type: Fix
id: 2566
time: '2026-07-15T18:42:52.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6308
- author: AppleSmithWorks
changes:
- message: New nuclear scientist PDA in the Engineer loadout.
type: Add
id: 2567
time: '2026-07-16T20:24:27.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6283
- author: ollyoaner
changes:
- message: Slime people upgrades! (Incl. ports from Impstation). Some slimeperson
characters might need their eye marking(s) fix due to them being eyeless by
default!
type: Add
id: 2568
time: '2026-07-17T03:50:51.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6288
- author: Velitation
changes:
- message: Added 2 new hats, 3 new neck items, 1 new coat and, 1 pair of shoes to
the mime loadout.
type: Add
- message: Mimes can now select which shoes they start with.
type: Tweak
id: 2569
time: '2026-07-17T04:31:23.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6307
- author: ArionGekkota
changes:
- message: 'Hitman: Added the ninja kit, for those who want a melee-oriented fight,
as well as its brand new medium-frequency blade!'
type: Add
- message: 'Hitman: Gave some extra goodies to the sharpshooter and poisoner kit.'
type: Tweak
- message: 'Hitman: Revamped the tracker kit to include way more tools to spy on
the crew.'
type: Tweak
- message: 'Hitman: Reworked the loud kit into the bounty hunter kit, now equipped
with a repeater and more cowboy attire'
type: Tweak
- message: 'Hitman: Merged the disguise and assassin kit into one kit, combining
stealth and the ability to blend in anywhere'
type: Tweak
- message: 'Hitman: Reworked the infiltrator kit into the saboteur kit, a kit more
focused on sabotage and setting up traps'
type: Tweak
- message: 'Hitman: Removed the escapist kit. The new ninja kit was given a scram
implant to compensate.'
type: Remove
id: 2570
time: '2026-07-17T04:40:05.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6270
- author: SumofThreeParts
changes:
- message: Traitors are now less likely to have the escape to Midpoint objective.
type: Tweak
id: 2571
time: '2026-07-19T16:19:30.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6323
- author: GooeyPancake
changes:
- message: Pills now have taste again! Sorry Lexorin-pilled people.
type: Add
id: 2572
time: '2026-07-19T16:38:26.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6299
- author: BriBrooo
changes:
- message: Added new kimono and sandals loadout options for the chef.
type: Add
id: 2573
time: '2026-07-20T00:12:52.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6341
- author: Eternally-Confused
changes:
- message: Cyborgs are once again able to "boop" and "whirr"
type: Add
id: 2574
time: '2026-07-20T00:24:43.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6310
- author: kotobdev
changes:
- message: The Ardent Censer no longer requires fuel for deconversions.
type: Tweak
id: 2575
time: '2026-07-20T17:38:51.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5016
- author: Halo3rat, kotobdev
changes:
- message: The Freighter Crew's Jumpsuit is now available in the AutoDrobe, for
those who value their dental hygiene.
type: Add
id: 2576
time: '2026-07-20T20:06:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6331
- author: Mnemotechnician, kotobdev, ShepardToTheStars
changes:
- message: You can now offer items to other players by pressing F, and then clicking
on them! They can accept by clicking on the alert on the side of their screen.
type: Add
id: 2577
time: '2026-07-20T20:13:58.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5597
- author: ShepardToTheStars
changes:
- message: Glimmer probers can once again turn on and lock into place when glimmer
is over 750.
type: Add
- message: Glimmer prober explosions are 1.5x bigger if glimmer is over 900. You
better build drainers! :)
type: Tweak
- message: The oracle can now give normality crystals when completing her requests.
type: Tweak
id: 2578
time: '2026-07-20T20:29:02.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6292
- author: keekee38
changes:
- message: Added the novice mark, to help show that you're new! It is on intern
roles by default, and optional for everyone
type: Add
- message: Some clothes now have examine text, in particular pride clothes.
type: Tweak
id: 2579
time: '2026-07-20T22:08:57.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6118
- author: Coryler
changes:
- message: Shadekin has arrived in the DeltaV sector.
type: Add
id: 2580
time: '2026-07-20T22:10:50.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5481
- author: sowelipililimute
changes:
- message: The crew monitor now reports global coordinate positions.
type: Tweak
id: 2581
time: '2026-07-20T22:20:12.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6326
- author: keekee38
changes:
- message: Vulpkanins can yip now.
type: Tweak
id: 2582
time: '2026-07-20T22:21:24.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6301
- author: pootslap
changes:
- message: Improvised shotgun shells use the old upstream crafting recipe.
type: Tweak
- message: The improvised shotgun is craftable once again.
type: Fix
id: 2583
time: '2026-07-20T22:22:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6327
- author: kotobdev
changes:
- message: Security cold weather ponchos are gone from loadouts and the SecDrobe.
type: Remove
id: 2584
time: '2026-07-20T22:44:01.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6332
- author: sowelipililimute
changes:
- message: Security now has access to evidence bags, for storing all the illegal
things that can be stored.
type: Add
id: 2585
time: '2026-07-20T23:17:53.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6280
- author: jessiscah23
changes:
- message: Added organizational capabilities to the cargo bounty computer.
type: Add
id: 2586
time: '2026-07-20T23:23:28.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6306
- author: Proxysseia
changes:
- message: (TEST MERGE) Increased traitor starting telecrystal balance from 20 to
30.
type: Tweak
id: 2587
time: '2026-07-20T23:37:07.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6275
- author: ArionGekkota
changes:
- message: reintroduced researchable PKA modkits
type: Add
- message: Changed the PKA to its current upstream state
type: Tweak
- message: Reduced the health of some salvage mobs
type: Tweak
id: 2588
time: '2026-07-20T23:46:11.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6258
- author: nlaky
changes:
- message: Fixed incorrect Vulpkanin mask sprites.
type: Fix
id: 2589
time: '2026-07-21T00:05:09.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6201
Order: 1
+16
View File
@@ -1071,4 +1071,20 @@
id: 123
time: '2026-06-12T17:16:00.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5940
- author: FieldCommand
changes:
- message: 'Mothership: Turrets have been constructed on the Xenoborg mothership!'
type: Add
id: 124
time: '2026-07-13T13:16:26.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6244
- author: FieldCommand
changes:
- message: 'Midpoint: Added a pool area to Midpoint.'
type: Add
- message: 'Midpoint: Securety on Midpoint is now blue!'
type: Tweak
id: 125
time: '2026-07-14T00:30:06.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6242
Order: 3
@@ -0,0 +1,9 @@
[game]
hostname = "[EN][MRP] Delta-v (Ψ) | Meridian [EU West]"
soft_max_players = 40
[hub]
tags = "lang:en-US,region:eu_w,rp:med,no_tag_infer"
[debug]
pow3r_disable_parallel = false
File diff suppressed because one or more lines are too long
@@ -16,3 +16,5 @@ delta-chat-emote-name-harpysquish = Squish
delta-chat-emote-name-quack = Quack
delta-chat-emote-name-squawk = Squawk
delta-chat-emote-name-horn = Horn
delta-chat-emote-name-yip = Yip
delta-chat-emote-msg-yip = yips.
@@ -1 +0,0 @@
damage-group-electronic = Electronic
@@ -0,0 +1,4 @@
dv-seen-inserted-item-name-modifier = {$baseName} with { INDEFINITE($contained) } { $contained }
dv-seen-inserted-item-examined =
.full = { CAPITALIZE(SUBJECT($container)) } has [color=paleturquoise]{ INDEFINITE($contained) } { $contained }[/color] in { SUBJECT($container) }.
.empty = { CAPITALIZE(SUBJECT($container)) } has nothing in { SUBJECT($container) }.
@@ -1 +1,5 @@
deltav-ghost-role-information-space-dragon-description = Call in 3 carp rifts and take over this quadrant! You must place a rift every 10 minutes or suffer the consequences!
ghost-role-information-space-dragon-matriarch-description = You are the space dragon matriarch. The crew is food, consume them all.
ghost-role-information-space-dragon-matriarch-name = Space Dragon Matriarch
ghost-role-information-space-dragon-matriarch-rules = Kill people, listen to the curator that spawned you in, kill people, dont die and kill people.
@@ -1,45 +1,44 @@
hitman-sharpshooter-kit-name = Sharpshooter kit
hitman-sharpshooter-kit-description =
A kit for those who prefer killing from afar.
Provides a Hristov with ammo along with an outfit in a briefcase.
it also provides thermal goggles to find your targets.
Provides a Hristov with ammo, thermal goggles and binoculars to spot
your target, and a stealth box and cigarettes to ease the nerves.
hitman-loud-kit-name = Loud kit
hitman-loud-kit-description =
hitman-bounty-hunter-kit-name = Bounty Hunter kit
hitman-bounty-hunter-kit-description =
A kit for those who like a direct method.
Provides a Python with Armor-Piercing rounds and two speedloaders.
Alongside an extra of an armor vest and no-slip shoes.
Provides a SKL93 and a python loaded with armor-piercing rounds, as well
as an extra speedloader and a cowboy outfit, armor vest included.
hitman-assassin-kit-name = Assassin kit
hitman-assassin-kit-description =
A kit for the quiet killers.
Provides a Cobra with an extra magazine and armor piercing throwing knives.
alongside night vision goggles and a radio jammer.
A kit for those who want to blend in.
Provides a Cobra with toxin and tranquilizer magazines, plus a set of
chameleon clothing, agent ID, fake mindshield and an identity mask implant.
hitman-ninja-kit-name = Ninja kit
hitman-ninja-kit-description =
A kit for those who want to fight up close.
Provides a medium frequency blade, throwing knives and a scram implant.
Plus no-slip shoes, smoke bombs and a combat medkit.
hitman-poisoner-kit-name = Poisoner kit
hitman-poisoner-kit-description =
A kit for those who enjoy chemicals.
Provides a syringe to use with a bottle of pax, toxin, mute toxin, and Nocturine.
A chemical synthesis kit is also provided.
Provides an advanced jet injector along with bottles of of Pax, Toxin,
Mute Toxin, and Nocturine. A chemical synthesis kit is also provided.
hitman-infiltration-kit-name = Infiltration kit
hitman-infiltration-kit-description =
hitman-saboteur-kit-name = Saboteur kit
hitman-saboteur-kit-description =
A kit for those who want to get anywhere.
Provides a cryptographic sequencer, syndicate jaws of life and stealth box.
hitman-disguise-kit-name = Disguise kit
hitman-disguise-kit-description =
A kit for those who want to be anyone.
Provides an Agent ID, chameleon clothing.
Plus a fake MindShield and voice mask implanter.
hitman-escapist-kit-name = Escapist kit
hitman-escapist-kit-description =
A kit for those who want to get out of anything.
Provides a DNA, freedom and scram implanter.
Provides a cryptographic sequencer, airlock access override and a
rapid construction device with extra compressed matter.
Plus a set of tools and a dead man's signaller perfect for laying down traps.
hitman-tracker-kit-name = Tracker kit
hitman-tracker-kit-description =
A kit for those who wish to know everything.
Provides a station master encryption key and universal pinpointer.
Plus a spy monitor.
Provides a station master encryption key and binary encryption key,
a spy monitor, a camera bug, an AI detector disguised as a multitool,
and a security hud disguised as sunglasses.
Plus a modified station map that can access crew records and universal pinpointer.
@@ -44,6 +44,7 @@ job-alt-title-plasma-scientist = Plasma Scientist
job-alt-title-senior-engineer = Engineering Mentor
job-alt-title-electrician = Electrician
job-alt-title-mechanic = Mechanic
job-alt-title-nuclear-scientist = Nuclear Scientist
job-alt-title-deck-worker = Deck Worker
job-alt-title-inventory-associate = Inventory Associate
@@ -0,0 +1,154 @@
# Ears
marking-EarsShadekinMotley = Motley Ears
marking-EarsShadekinMotley-shadowkin = Ears
marking-EarsShadekinMotley-motley_secondary = Pattern
marking-EarsShadekinShady = Dark Ears
marking-EarsShadekinShady-shady = Ears
marking-EarsShadekinStriped = Striped Ears
marking-EarsShadowkinStriped-shadowkin = Ears
marking-EarsShadowkinStriped-shadowkin_stripes = Stripes
marking-EarsShadekinPiercingAll = Ears with Piercings
marking-EarsShadekinPiercingAll-shadowkin = Ears
marking-EarsShadekinPiercingAll-piercing_all = Piercings
marking-EarsShadekinPiercingLeft = Ears with Piercing (L)
marking-EarsShadekinPiercingLeft-shadowkin = Ears
marking-EarsShadekinPiercingLeft-piercing_left = Piercing
marking-EarsShadekinPiercingRight = Ears with Piercing (R)
marking-EarsShadekinPiercingRight-shadowkin = Ears
marking-EarsShadekinPiercingRight-piercing_right = Piercing
marking-EarsShadekinRingedAll = Ears with Rings
marking-EarsShadekinRingedAll-shadowkin = Ears
marking-EarsShadekinRingedAll-ringed_all_secondary = Rings
marking-EarsShadekinRingedLeft = Ears with Ring (L)
marking-EarsShadekinRingedLeft-shadowkin = Ears
marking-EarsShadekinRingedLeft-ringed_left_secondary = Ring
marking-EarsShadekinRingedRight = Ears with Ring (R)
marking-EarsShadekinRingedRight-shadowkin = Ears
marking-EarsShadekinRingedRight-ringed_right_secondary = Ring
marking-EarsShadekinGauzedAll = Gauzed Ears
marking-EarsShadekinGauzedAll-shadowkin = Ears
marking-EarsShadekinGauzedAll-gauze_ear_all_default = Gauze
marking-EarsShadekinGauzedLeft = Ear Bandage (L)
marking-EarsShadekinGauzedLeft-shadowkin = Ears
marking-EarsShadekinGauzedLeft-gauze_ear_l_default = Bandage
marking-EarsShadekinGauzedRight = Ear Bandage (R)
marking-EarsShadekinGauzedRight-shadowkin = Ears
marking-EarsShadekinGauzedRight-gauze_ear_r_default = Bandage
marking-EarsShadekinFluffy = Fluffy Ears
marking-EarsShadekinFluffy-fluffy_default = Ears
marking-EarsShadekinFluffyButterfly = Fluffy Ears, Butterfly
marking-EarsShadekinFluffyButterfly-fluffy_default = Ears
marking-EarsShadekinFluffyButterfly-fluffy_butterfly = Pattern
marking-EarsShadekinFluffyCowling = Fluffy Ears, Spotted
marking-EarsShadekinFluffyCowling-fluffy_default = Ears
marking-EarsShadekinFluffyCowling-fluffy_cowling = Pattern
marking-EarsShadekinFluffyCrow = Fluffy Ears, Crow
marking-EarsShadekinFluffyCrow-fluffy_default = Ears
marking-EarsShadekinFluffyCrow-fluffy_crow = Pattern
marking-EarsShadekinFluffyMotley = Fluffy Ears, Bright
marking-EarsShadekinFluffyMotley-fluffy_default = Ears
marking-EarsShadekinFluffyMotley-fluffy_motley = Pattern
marking-EarsShadekinFluffySpidy = Fluffy Ears, Spidy
marking-EarsShadekinFluffySpidy-fluffy_default = Ears
marking-EarsShadekinFluffySpidy-fluffy_spidy = Pattern
marking-EarsShadekinFluffyRingedAll = Fluffy Ears, with Rings
marking-EarsShadekinFluffyRingedAll-fluffy_default = Ears
marking-EarsShadekinFluffyRingedAll-fluffy_ringed_all = Rings
marking-EarsShadekinFluffyRingedLeft = Fluffy Ears, with Ring (L)
marking-EarsShadekinFluffyRingedLeft-fluffy_default = Ears
marking-EarsShadekinFluffyRingedLeft-fluffy_ringed_left = Ring
marking-EarsShadekinFluffyRingedRight = Fluffy Ears, with Ring (R)
marking-EarsShadekinFluffyRingedRight-fluffy_default = Ears
marking-EarsShadekinFluffyRingedRight-fluffy_ringed_right = Ring
marking-EarsShadekinSaggy = Drooping Ears
marking-EarsShadekinSaggy-saggy_default = Ears
marking-EarsShadekinSaggyBrawly = Drooping Ears, Patterned
marking-EarsShadekinSaggyBrawly-saggy_default = Ears
marking-EarsShadekinSaggyBrawly-saggy_brawly = Pattern
marking-EarsShadekinSaggyZebra = Drooping Ears, Striped
marking-EarsShadekinSaggyZebra-saggy_default = Ears
marking-EarsShadekinSaggyZebra-saggy_zebra = Stripes
marking-EarsShadekinSaggyGradient = Drooping Ears, Gradient
marking-EarsShadekinSaggyGradient-saggy_default = Ears
marking-EarsShadekinSaggyGradient-saggy_gradient = Gradient
marking-EarsShadekinSaggyGauzedAll = Drooping Ears, Gauzed
marking-EarsShadekinSaggyGauzedAll-saggy_default = Ears
marking-EarsShadekinSaggyGauzedAll-saggy_gauze_all = Gauze
marking-EarsShadekinSaggyGauzedLeft = Drooping Ears, Ear Bandage (L)
marking-EarsShadekinSaggyGauzedLeft-saggy_default = Ears
marking-EarsShadekinSaggyGauzedLeft-saggy_gauze_l = Bandage
marking-EarsShadekinSaggyGauzedRight = Drooping Ears, Ear Bandage (R)
marking-EarsShadekinSaggyGauzedRight-saggy_default = Ears
marking-EarsShadekinSaggyGauzedRight-saggy_gauze_r = Bandage
marking-EarsShadekinShort = Short Ears
marking-EarsShadekinShort-short_default = Ears
marking-EarsShadekinShortButterfly = Short Ears, Decorated
marking-EarsShadekinShortButterfly-short_default = Ears
marking-EarsShadekinShortButterfly-short_butterfly = Pattern
marking-EarsShadekinShortRingedAll = Short Ears, with Rings
marking-EarsShadekinShortRingedAll-short_default = Ears
marking-EarsShadekinShortRingedAll-short_ringed_all = Rings
marking-EarsShadekinShortRingedLeft = Short Ears, with Ring (L)
marking-EarsShadekinShortRingedLeft-short_default = Ears
marking-EarsShadekinShortRingedLeft-short_ringed_left = Ring
marking-EarsShadekinShortRingedRight = Short Ears, with Ring (R)
marking-EarsShadekinShortRingedRight-short_default = Ears
marking-EarsShadekinShortRingedRight-short_ringed_right = Ring
marking-EarsShadekinBull = Straight Ears
marking-EarsShadekinBull-bull_default = Ears
marking-EarsShadekinBullSmooth = Straight Ears, Outlined
marking-EarsShadekinBullSmooth-bull_default = Ears
marking-EarsShadekinBullSmooth-bull_smooth = Inner ears
marking-EarsShadekinAqua = Aqua Ears
marking-EarsShadekinAqua-aqua_default = Ears
marking-EarsShadekinAquaIncolor = Aqua Ears, Colored
marking-EarsShadekinAquaIncolor-aqua_default = Ears
marking-EarsShadekinAquaIncolor-aqua_incolor = Inner ears
# Tails
marking-TailShadekin = Long Tail
marking-TailShadekinBig = Big Tail
marking-TailShadekinShorter = Short Tail
marking-TailShadekinShorter-shadekin_shorter_over = Tail
marking-TailShadekinShorterBrush = Short Tail, Furry
marking-TailShadekinShorterBrush-shadekin_shorter_over = Tail
marking-TailShadekinShorterBrush-shorter_brush_over = Tail tip
marking-TailShadekinMedium = Medium Tail
marking-TailShadekinMedium-shadekin_medium_front = Tail
marking-TailShadekinMediumTwoColored = Medium Tail, Two-Toned
marking-TailShadekinMediumTwoColored-shadekin_medium_front = Tail
marking-TailShadekinMediumTwoColored-medium_twocolored_over = Tail underside
# Overlays
marking-BodyShadekinArrow = Arrow Marking
marking-BodyShadekinArrow-body_arrow = Marking
marking-BodyShadekinBlackHole = Black Hole Marking
marking-BodyShadekinBlackHole-body_blackhole = Marking
marking-BodyShadekinBrace = Bracelet Marking
marking-BodyShadekinBrace-body_brace = Marking
marking-BodyShadekinBrawly = Combat Marking
marking-BodyShadekinBrawly-body_brawly = Marking
marking-BodyShadekinHeart = Heart Marking
marking-BodyShadekinHeart-body_heart = Marking
marking-BodyShadekinInk = Ink Marking
marking-BodyShadekinInk-body_ink = Marking
marking-BodyShadekinInk2 = Ink Marking 2
marking-BodyShadekinInk2-body_ink2 = Marking
marking-BodyShadekinInk3 = Ink Marking 3
marking-BodyShadekinInk3-body_ink3 = Marking
marking-BodyShadekinInk4 = Ink Marking 4
marking-BodyShadekinInk4-body_ink4 = Marking
marking-BodyShadekinInk5 = Ink Marking 5
marking-BodyShadekinInk5-body_ink5 = Marking
marking-BodyShadekinInk6 = Spiritual Ink Marking
marking-BodyShadekinInk6-body_ink6 = Marking
marking-BodyShadekinInkAnim = Spiral Ink Marking
marking-BodyShadekinInkAnim-body_ink_anim = Marking
marking-BodyShadekinLines = Lines Marking
marking-BodyShadekinLines-body_lines = Marking
marking-BodyShadekinNeck = Neck Marking
marking-BodyShadekinNeck-body_neck = Marking
marking-BodyShadekinShield = Protective Marking
marking-BodyShadekinShield-body_shield = Marking
marking-BodyShadekinVacuum = Open Marking
marking-BodyShadekinVacuum-body_vacuum = Marking
@@ -0,0 +1,54 @@
# Ears
marking-SlimeLongEars = Long Ears Standard
marking-SlimeLongEars-slime_ears_standard = Long Ears Standard
marking-SlimeEarsWide = Long Ears Wide
marking-SlimeEarsWide-slime_ears_wide = Long Ears Wide
marking-SlimeEarsSmall = Long Ears Small
marking-SlimeEarsSmall-slime_ears_small = Long Ears Small
marking-SlimeEarsUpwards = Long Ears Upwards
marking-SlimeEarsUpwards-slime_ears_upwards = Long Ears Upwards
marking-SlimeEarsTall = Long Ears Tall
marking-SlimeEarsTall-slime_ears_tall = Long Ears Tall
marking-SlimeEarsThin = Long Ears Thin
marking-SlimeEarsThin-slime_ears_thin = Long Ears Thin
# Eyes
marking-SlimeEyesDroopyRight = Droopy Eyes (Right)
marking-SlimeEyesDroopyRight-droopyR = Droopy Eyes (Right)
marking-SlimeEyesFourEyes = 4 Eyes
marking-SlimeEyesFourEyes-foureyes = 4 Eyes
marking-SlimeEyesLEyeLower = Left Eye (Lower)
marking-SlimeEyesLEyeLower-lefteye_lower = Left Eye (Lower)
marking-SlimeEyesREyeLower = Right Eye (Lower)
marking-SlimeEyesREyeLower-righteye_lower = Right Eye (Lower)
# Makeup
marking-MakeupFoureyesEyeshadow-foureyes_eyeshadow = Eyeshadow Foureyes
marking-MakeupFoureyesEyeshadow = Eyeshadow Foureyes
marking-MakeupDroopyLEyeshadowUpper = Eyeshadow Droopy Upper (Left)
marking-MakeupDroopyLEyeshadowUpper-droopyL_eyeshadow_upper = Eyeshadow Droopy Upper (Left)
marking-MakeupDroopyLEyeshadowLower = Eyeshadow Droopy Lower (Left)
marking-MakeupDroopyLEyeshadowLower-droopyL_eyeshadow_lower = Eyeshadow Droopy Lower (Left)
marking-MakeupDroopyREyeshadowUpper = Eyeshadow Droopy Upper (Right)
marking-MakeupDroopyREyeshadowUpper-droopyR_eyeshadow_upper = Eyeshadow Droopy Upper (Right)
marking-MakeupDroopyREyeshadowLower = Eyeshadow Droopy Lower (Right)
marking-MakeupDroopyREyeshadowLower-droopyR_eyeshadow_lower = Eyeshadow Droopy Lower (Right)
# Chest
marking-TorsoBitsF = Torso Bits
marking-TorsoBitsF-torsobits_f = Torso Bits
marking-TorsoBitsM = Torso Bits
marking-TorsoBitsM-torsobits_m = Torso Bits

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