Compare commits

...
Author SHA1 Message Date
Delta-V bot 515fd80845 Automatic changelog update 2026-09-20 22:11:19 +02:00
freezer dog 99a9f47e94 med kits dont fit in pockets (#6523)
yep that works
2026-09-20 20:10:55 +00:00
github-actions[bot]andDeltaV-Bot f5d4de4cf3 Update Credits (#6526)
Co-authored-by: DeltaV-Bot <github@deltav.gay>
2026-09-20 04:52:10 +02:00
Delta-V bot 6edb3a2961 Automatic changelog update 2026-09-17 16:05:13 +02:00
ce0410c41e [multi-antag changes] freelancing. (#6495)
* freelancing

* thief roundstart freelance

* Update Resources/Prototypes/Roles/Antags/thief.yml

Co-authored-by: Radezolid <snappednexus@gmail.com>
Signed-off-by: storm! <253825839+stormyatt@users.noreply.github.com>

* easy changes

---------

Signed-off-by: storm! <253825839+stormyatt@users.noreply.github.com>
Co-authored-by: stormyatt <stormyatt@users.noreply.github.com>
Co-authored-by: Radezolid <snappednexus@gmail.com>
2026-09-17 11:04:52 -03:00
Delta-V bot d800d4a8c1 Automatic changelog update 2026-09-17 16:03:55 +02:00
Apersos-coll cea62ee53d Fixes Unstable Core Refractors wording so it doesnt cause errors (#6517)
Fixes-The-Wording
weh
2026-09-17 11:03:34 -03:00
Delta-V bot c3bb3f001a Automatic changelog update 2026-09-17 12:41:22 +02:00
Apersos-collandpre-commit-ci[bot] a332245ff0 EPU-U001 Integrity (Another CC Official gun) (#6507)
* Added Commander Tex's Pistol of doom and despare

* Downgraded damage/dps
freedom made the description alot more light and it now referenced tex barely, so its basically not only his weapon but now just a CC official pistol that anyone can use and the description helps

* Update battery_guns.yml

Change numba 1

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

* Update battery_guns.yml 2

slight change again, and some fixes to the whachamacallit

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

* Removed paralyzer bolt

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

* whoopsies, forgot to fix the copyright to be ME cause I made this, and freedom helped :)

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

* Fixed name on stuffs so it functions

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

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

---------

Signed-off-by: Apersos-coll <collsherlo@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-09-17 12:41:01 +02:00
Delta-V bot f94cab57df Automatic changelog update 2026-09-17 06:23:05 +02:00
742524b2ff Asakim Tweaks (#6452)
* yippee

* pulser buff

* rulesops

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

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

* changes made i hope

* Update objectiveGroups.yml

* Update Resources/Prototypes/_Mono/Entities/Clothing/OuterClothing/Hardsuits/asakim.yml

Signed-off-by: Radezolid <snappednexus@gmail.com>

---------

Signed-off-by: Radezolid <snappednexus@gmail.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-09-17 04:22:45 +00:00
Delta-V bot cdb104ee2e Automatic changelog update 2026-09-17 06:19:59 +02:00
freezer dog 180281ae0d slimes can have prosthetic limbs (#6496)
yep
2026-09-17 01:19:40 -03:00
Delta-V bot 0a3507c93b Automatic changelog update 2026-09-17 06:05:39 +02:00
pixelStrifeandRadezolid 2efc9871db Ovinia suffocation noises: Enabled (#6481)
* add ovinia suffocation

* Update Resources/Prototypes/_DEN/Voice/speech_emote_sounds.yml

Co-authored-by: Radezolid <snappednexus@gmail.com>
Signed-off-by: pixelStrife <46169994+pixelStrife@users.noreply.github.com>

* Update Resources/Prototypes/_DEN/Voice/speech_emote_sounds.yml

Co-authored-by: Radezolid <snappednexus@gmail.com>
Signed-off-by: pixelStrife <46169994+pixelStrife@users.noreply.github.com>

---------

Signed-off-by: pixelStrife <46169994+pixelStrife@users.noreply.github.com>
Co-authored-by: Radezolid <snappednexus@gmail.com>
2026-09-17 01:05:18 -03:00
Delta-V bot 814ef07035 Automatic changelog update 2026-09-17 05:01:56 +02:00
657f1fd534 Changes the sprite for the air sensor (#6340)
* Changes the sprite for the air sensor

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

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

* Forgot to comment the assembly entity

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

* Adds gray air sensors

* Adds the extensions of the gray air sensors

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

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

* Update freezer.yml

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

* Update Resources/Prototypes/_DV/Entities/Structures/Specific/Atmospherics/sensor.yml

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

* Update Resources/Prototypes/_DV/Entities/Structures/Specific/Atmospherics/sensor.yml

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

* Update Resources/Prototypes/_DV/Entities/Structures/Specific/Atmospherics/vox.yml

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

* Update Resources/Prototypes/_DV/Entities/Structures/Specific/Atmospherics/sensor.yml

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

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

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

* Fixes explosions in the code

* Fixed the meta.json order

Signed-off-by: Radezolid <snappednexus@gmail.com>

---------

Signed-off-by: BriBrooo <45323530+Bribrooo@users.noreply.github.com>
Signed-off-by: Radezolid <snappednexus@gmail.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>
Co-authored-by: Radezolid <snappednexus@gmail.com>
2026-09-17 03:01:35 +00:00
Delta-V bot a8e51dffc3 Automatic changelog update 2026-09-16 14:44:57 +02:00
84c7e3d877 Unstable Core Refractor (2 electric boogaloo) (#6491)
* Added in -
UCR (unstable core refractor) a hard to obtain crew side maybe heavy laser gun which has very low capacity high dps and slows you down a shit ton along side that it cant aim for shit and only does radiation damage which is countered by rad suit and thermal suit for syndis. its fully sprited even for its back and suitstorage sprites...
Added in -
Specialized weapon parts which holds two new parts to create the UCR being the Unstable reactor core and the Unstable Reactor Housing which will later combine to make the weapon when i figure that out
changed -
loot tables to include in legendary the unstable reactor core

* added everything else
 fixed up inhand sprites for the core, and gave it some more omph interms of radiation because i hate salv
 now its craftable in the crafting menu when you get the housing and the core and you just have both of em and put it together decently not fast
 yeah crafting systems suck i had to make like 3 new stuffs and add to like 2 already existing thingys...
 also i forgot to add reactor core to legdary loot table, now its in
 also its in the sec fab now and blacklisted from portable recharger not like it would do you any good but it would negate the speed downisde which is a big part of it

* small final fixes
fixed unstable reactor core spawning in sets of 3 to 5 now it only spawns 1 (its still really fuckin rare)

changed unstable core refractor's sprite thingy to fit in with the rest of them in terms of naming convention

changed icon and base sprites so they were more shaded and look less odd

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

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

* hot fix :)
changed graph name to UnstableCoreRefractor

* Fixing single word

added word core in between the UnstableReactor in the Unstable Reactor Housing item thingy

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

* reworks the thingy
reverse bloom on the gun allows it to be both "unstable" and useable
some other stuff which are just fixes

* made core buyable
made core less radioactive
stat changes for gun so it focusses fire faster and has a bit faster generation

* Made Unstable Beam projectiles have unique textures i made :)
buffed projectiles to 6 damage a hit instead of 5 cause radiation damage is so weak, now its more viable in actual combat :)

* recharge buff cause its so slow

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

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

* fixed it, the crate i had to fix while updating it i missplaced the y and the p in type...

* Update Resources/Prototypes/_DV/Entities/Objects/Misc/specialized_weapon_parts.yml

Co-authored-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>
Signed-off-by: Apersos-coll <collsherlo@gmail.com>

* Update Resources/Prototypes/Research/arsenal.yml

Co-authored-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>
Signed-off-by: Apersos-coll <collsherlo@gmail.com>

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

Co-authored-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>
Signed-off-by: Apersos-coll <collsherlo@gmail.com>

* Update Resources/Prototypes/Entities/Markers/Spawners/Random/Salvage/tables_loot.yml

Co-authored-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>
Signed-off-by: Apersos-coll <collsherlo@gmail.com>

* Update Resources/Prototypes/_DV/Entities/Objects/Misc/specialized_weapon_parts.yml

Co-authored-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>
Signed-off-by: Apersos-coll <collsherlo@gmail.com>

* crate will no longer spill radiation onto the populus of cargonia

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

* Re increased radiation due to the crate not leaking it so now its a actual threat and hard to store, instead of lightly tickling you over the course of 9 minutes

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

* all requested maintainer changes, and we are donzo!!!!!!

* Update Resources/Prototypes/_DV/Entities/Objects/Misc/specialized_weapon_parts.yml

Signed-off-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>

* Update Resources/Prototypes/_DV/Entities/Objects/Misc/specialized_weapon_parts.yml

Signed-off-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>

---------

Signed-off-by: Apersos-coll <collsherlo@gmail.com>
Signed-off-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Sir Warock <67167466+SirWarock@users.noreply.github.com>
2026-09-16 12:44:36 +00:00
Delta-V bot d151384db8 Automatic changelog update 2026-09-16 14:31:26 +02:00
SumofThreeParts 7bcc06b46a Glimmer prober lockout at 600 instead of 750 (#6493)
Glimmer probers lockout at 600 instead of 750

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>
2026-09-16 09:31:05 -03:00
Delta-V bot e409e98bf6 Automatic changelog update 2026-09-14 19:45:03 +02:00
760af2e261 Fix beer bottles (#6503)
* fix:beer bottles were missing the DrinkBottle tag

* Revert "fix:beer bottles were missing the DrinkBottle tag"

This reverts commit 320bdfeaf9.

* fix:beer bottles were missing the DrinkBottle tag

* Update Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml

missing DeltaV tag to specify that it's a delta-v specific change

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

---------

Signed-off-by: pinoinha <55506432+Pinoinha@users.noreply.github.com>
Co-authored-by: Marina Barros <azulmarina799@gmail.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-09-14 12:44:42 -05:00
Delta-V bot ebc0340fc9 Automatic changelog update 2026-09-14 00:20:01 +02:00
KOTOB e8b6c42de4 Fix/Lower Asakim Weight (#6455)
* whoop

* nuke from antag table

* we love webedits in this household

Signed-off-by: KOTOB <59124164+kotobdev@users.noreply.github.com>

---------

Signed-off-by: KOTOB <59124164+kotobdev@users.noreply.github.com>
2026-09-13 15:19:39 -07:00
github-actions[bot]andDeltaV-Bot 5e0d668f60 Update Credits (#6505)
Co-authored-by: DeltaV-Bot <github@deltav.gay>
2026-09-13 04:36:32 +02:00
Delta-V bot 2c1084da78 Automatic changelog update 2026-09-11 01:40:04 +02:00
BarryNorfolk 9304aad604 Swap emergency shuttles to use NTNet (#6497) 2026-09-10 19:39:43 -04:00
Delta-V bot 5132e64a0f Automatic changelog update 2026-09-09 17:49:38 +02:00
SumofThreePartsandpre-commit-ci[bot] d2bf1e9a39 Adding the Anaconda (#6458)
* Creating the Anaconda

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

* hashtag balance

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

* Adding the anaconda sprites

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

* Delete anaconda directory

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

* Adding the anaconda sprites

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

* whoops!

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

* yuuuup. adding tha andaconda sprites. again

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

* doing the thing!!!

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

* part one of adding it to uplink 

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

* whoops!

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

* guh

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

* part 2 of adding anaconda to uplink

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

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

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

* doing the thang 

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

* adding the thang i was told to

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

* adding it but for real

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

* oh yeah the description

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

* grrrr grrr not correct

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

* guh

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

---------

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-09-09 15:49:17 +00:00
Delta-V bot 865d254cd4 Automatic changelog update 2026-09-09 16:55:05 +02:00
Astra 29ec2e659f Give shadekin hair (#6453)
Add shadekin hair
2026-09-09 09:54:44 -05:00
Delta-V bot 690f64d592 Automatic changelog update 2026-09-09 16:18:58 +02:00
pixelStrife b6e018eb18 Namespace drink metabolites (#6486)
* switched Silencer parent to BaseDrink to revert to pre-Metabolite behavior (non-alcoholic)

* Bring namespace drinks in line with upstream, using the new(-ish) Metabolites system in place of the AdjustReagent effect
2026-09-09 09:18:38 -05:00
Delta-V bot 8bcddf4333 Automatic changelog update 2026-09-09 16:15:50 +02:00
34940ecde7 The Pitbull Update of Doom and Despair (#6449)
* it begins.

* THEYRE IN THE VENTS

* Update pitbull.yml

* I AM THE ONE WHO COLLECTS THE PITBULLS

* Fuck you

* THAT IS BULLSHIT BLAZING

* Throw a small child into upper orbit

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

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

* 100 pitbull names

* changed one

* sorry one last pitbull name

* Update pitbull_names.yml

---------

Co-authored-by: Solaris <63768197+Solaris7518@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-09-09 09:15:30 -05:00
Delta-V bot dafd97e6e1 Automatic changelog update 2026-09-09 16:07:57 +02:00
einknusprigestoastandpre-commit-ci[bot] 593d35903d ERT Gamma changes + gun addition - The return of the fake balancing. (#6239)
* Added Jackdaw and Kammerer

* ERT hardsuit change

* Jackdaw changes

* [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-09-09 09:07:34 -05:00
Delta-V bot 1856f65a18 Automatic changelog update 2026-09-07 02:34:02 +02:00
brainslushie 9066c4af7f Surplus boots - cosmetic jackboots (#6472)
* +surplus boots

* surplus boots in vendor
2026-09-06 21:33:42 -03:00
Stxcking cf9a10af4e PORT: Thaven Markings and Organs from Macrocosm (#6162)
* Can't go wrong with Sprites

* .ftl and .yml files

* displacement + parts + organs

* marking and displacement yaml

* does arent real...yet

* Imp dupe nuke

* go my human+

* no shaders :<

* whoopsie

idk how
2026-09-06 21:18:44 -03:00
Delta-V bot 2d7af5622f Automatic changelog update 2026-09-07 02:17:42 +02:00
nlaky 974f5ff5fa Vulp alt tail wag + fade tip fix (#6480)
* Add wag markings for vulp alt tail

* Fix tip markings used for fade tails
2026-09-06 21:17:22 -03:00
Delta-V bot 88dc8af9a4 Automatic changelog update 2026-09-07 01:36:12 +02:00
BriBrooo 7c33759cbe Update Botanicals.xml (#6483)
Fixes a duplicate entry in the botanical reagent guidebook.
2026-09-06 20:35:52 -03:00
Delta-V bot baf009af3a Automatic changelog update 2026-09-05 16:03:30 +02:00
Field Command b59dfa8991 Central Command remake! (#6198)
* New Central Command

* Me forget

* typos and name change

* Fix and typo

* More polish

* Requested Fixes
2026-09-05 09:03:08 -05:00
github-actions[bot]andDeltaV-Bot e43a587ede Update Credits (#6465)
Co-authored-by: DeltaV-Bot <github@deltav.gay>
2026-08-30 05:00:27 +02:00
Delta-V bot 00d77213c6 Automatic changelog update 2026-08-29 01:54:53 +02:00
VapeandVanessa 389a616138 Ramping Scheduler adjustments and changes (#6440)
* Update roundstart.yml

* updakes

* Rnd 2 fight

* Changes done

* Apply suggestion from @ShepardToTheStars

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

* Apply batched 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: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-08-28 23:54:33 +00:00
Delta-V bot 07b029ff2b Automatic changelog update 2026-08-28 18:38:29 +02:00
Carol 1043b40246 Added caseless shotgun shells (#6457)
added caseless shotgun shells
2026-08-28 11:38:08 -05:00
Delta-V bot d0385ab8bb Automatic changelog update 2026-08-27 21:26:28 +02:00
03347ed416 Inverse Labels and Handlabeler menu (#6432)
Merge pull request #1120 from oooielp/label-invert (#783)

Co-authored-by: Khaomi <46065349+Khaomi@users.noreply.github.com>
Co-authored-by: Superlagg <sprambersonson@gmail.com>
2026-08-27 14:26:07 -05:00
Delta-V bot e9f0148287 Automatic changelog update 2026-08-27 21:24:33 +02:00
SumofThreePartsandVanessa 0f7131d9e7 Buffing the Hushpup (#6438)
* Buffing the Hushpup

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

* Doing the thing

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* doing the thang

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

* Changing it back

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

---------

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>
Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-08-27 16:24:13 -03:00
Delta-V bot bf9b42c76c Automatic changelog update 2026-08-27 20:38:01 +02:00
a635429d3e Communications console & screens overhaul (#5954)
* i'm going insane from screens

* some wiring

* screemes

* holy shit adhd lock-in

* incomplete

* its FUCKING DONE

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

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

* zeta

* mrrrp

* test fix

* fix arrivals

* fix misnetwork

* Fix iteration outline. Fixed all headers showing if all options where hidden. Added access requirement to keycard auth mechnism. Added countdown. Fixed ninja and fugitive. Fixed AI and aghost.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Vanessa <vanessalouwagie@gmail.com>
2026-08-27 13:37:40 -05:00
Delta-V bot bd1e4224cd Automatic changelog update 2026-08-27 20:32:18 +02:00
Vanessa 568621858e Trees are now actually rooted and cannot move. (#6456) 2026-08-27 13:31:58 -05:00
Delta-V bot 3df2209227 Automatic changelog update 2026-08-27 16:29:59 +02:00
1da052e36f Letting the patos be purchased (#6361)
* Making Patos a thing you can buy

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

* Update armory.yml

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

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

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

* Update cargo_armory.yml

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

* Update armory.yml

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

* Update armory.yml

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

* Update armory.yml

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

* Update magazine amount in armory.yml

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

* thankies

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

* thankies 2

Co-authored-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.com>

---------

Signed-off-by: SumofThreeParts <its.a.joke1000@gmail.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-08-27 11:29:39 -03:00
Delta-V bot 66b95a46ed Automatic changelog update 2026-08-26 10:35:09 +02:00
Vanessa 92ba9edeee Small Midround Antag Balance Pass (#6410)
* Nerfed skia regen.

* Nerfed ninja dash

* Fix ninja agent id

* Skia tweak

* Add reveal to rev attack

* Apply suggestion from @ShepardToTheStars

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

---------

Signed-off-by: Vanessa <908648+ShepardToTheStars@users.noreply.github.com>
2026-08-26 10:34:48 +02:00
Delta-V bot 680092719f Automatic changelog update 2026-08-24 18:23:27 +02:00
Vanessa 1afbadd404 Fix Health Analyzer Not Showing Traits (#6446)
* Fixed some alerts not showing in the health analyzer

* This is upstream now so removing comments
2026-08-24 11:23:07 -05:00
Delta-V bot 2c190cf2f2 Automatic changelog update 2026-08-24 17:14:11 +02:00
Vanessa 17d798a3e8 Stole Thief Gloves from the Uplink (#6425)
Stole thief gloves from the uplink.
2026-08-24 10:13:51 -05:00
Delta-V bot 287714d87b Automatic changelog update 2026-08-23 17:00:54 +02:00
Vanessa 029aaf8127 Fix Mothroach Grenades (#6447)
Fix mothroach grenades
2026-08-23 10:00:34 -05:00
673 changed files with 142720 additions and 45198 deletions
@@ -28,7 +28,6 @@ namespace Content.Client.Communications.UI
_menu.OnBroadcast += BroadcastButtonPressed;
_menu.OnAlertLevel += AlertLevelSelected;
_menu.OnEmergencyLevel += EmergencyShuttleButtonPressed;
_menu.OnExfiltrationLevel += ExfiltrationShuttleButtonPressed; // DeltaV - Exfiltration shuttle
}
public void AlertLevelSelected(string level)
@@ -48,13 +47,6 @@ namespace Content.Client.Communications.UI
CallShuttle();
}
// Begin DeltaV - Exfiltration Shuttle
public void ExfiltrationShuttleButtonPressed()
{
SendMessage(new CommunicationsConsoleExfiltrationShuttleMessage(!_menu!.CountdownStarted));
}
// End DeltaV - Exfiltration Shuttle
public void AnnounceButtonPressed(string message)
{
var maxLength = _cfg.GetCVar(CCVars.ChatMaxAnnouncementLength);
@@ -94,13 +86,6 @@ namespace Content.Client.Communications.UI
_menu.CurrentLevel = commsState.CurrentAlert;
_menu.CountdownEnd = commsState.ExpectedCountdownEnd;
// Begin DeltaV - Exfiltration Shuttle
_menu.CanExfiltrate = commsState.CanCall;
_menu.ExfiltrationCountdownEnd = commsState.ExpectedExfiltrationCountdownEnd;
_menu.ExfiltrationShuttleButton.Disabled = !_menu.CanExfiltrate;
// End DeltaV - Exfiltration Shuttle
_menu.UpdateCountdown();
_menu.UpdateAlertLevels(commsState.AlertLevels, _menu.CurrentLevel);
_menu.AlertLevelButton.Disabled = !_menu.AlertLevelSelectable;
@@ -52,19 +52,10 @@
<RichTextLabel Name="CountdownLabel"/>
<!-- DeltaV - Exfiltration Shuttle -->
<RichTextLabel Name="ExfiltrationCountdownLabel"/>
<Button Name="EmergencyShuttleButton"
Access="Public"
Text="Placeholder Text"
ToolTip="{Loc 'comms-console-menu-emergency-shuttle-button-tooltip'}"/>
<!-- DeltaV - Exfiltration Shuttle -->
<Button Name="ExfiltrationShuttleButton"
Access="Public"
Text="Placeholder Text"
ToolTip="{Loc 'comms-console-menu-exfiltration-shuttle-button-tooltip'}"/>
</BoxContainer>
</BoxContainer>
</BoxContainer>
@@ -29,12 +29,6 @@ namespace Content.Client.Communications.UI
public event Action<string>? OnAnnounce;
public event Action<string>? OnBroadcast;
// Begin DeltaV - Exfiltration Shuttle
public bool CanExfiltrate;
public TimeSpan? ExfiltrationCountdownEnd;
public event Action? OnExfiltrationLevel;
// End DeltaV - Exfiltration Shuttle
public CommunicationsConsoleMenu()
{
IoCManager.InjectDependencies(this);
@@ -78,18 +72,12 @@ namespace Content.Client.Communications.UI
EmergencyShuttleButton.OnPressed += _ => OnEmergencyLevel?.Invoke();
EmergencyShuttleButton.Disabled = !CanCall;
// Begin DeltaV - Exfiltration Shuttle
ExfiltrationShuttleButton.OnPressed += _ => OnExfiltrationLevel?.Invoke();
ExfiltrationShuttleButton.Disabled = !CanExfiltrate;
// End DeltaV - Exfiltration Shuttle
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
UpdateCountdown();
UpdateExfiltrationCountdown(); // DeltaV - Exfiltration shuttle
}
// The current alert could make levels unselectable, so we need to ensure that the UI reacts properly.
@@ -129,25 +117,6 @@ namespace Content.Client.Communications.UI
}
}
// Begin DeltaV - Exfiltration Shuttle
public void UpdateExfiltrationCountdown()
{
if (ExfiltrationCountdownEnd is null)
{
ExfiltrationCountdownLabel.SetMessage(string.Empty);
ExfiltrationShuttleButton.Text = Loc.GetString("comms-console-menu-call-exfiltration");
return;
}
var exfiltrationDiff = MathHelper.Max((ExfiltrationCountdownEnd - _timing.CurTime) ?? TimeSpan.Zero, TimeSpan.Zero);
ExfiltrationShuttleButton.Text = Loc.GetString("comms-console-menu-recall-exfiltration");
var exfiltrationInfoText = Loc.GetString("comms-console-menu-exfiltration-time-remaining",
("time", exfiltrationDiff.ToString(@"hh\:mm\:ss", CultureInfo.CurrentCulture)));
ExfiltrationCountdownLabel.SetMessage(exfiltrationInfoText);
}
// End DeltaV - Exfiltration Shuttle
public void UpdateCountdown()
{
if (!CountdownStarted)
@@ -179,9 +179,12 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
var unborgable = _unborgable.IsUnborgable(target.Value);
var redshirt = _redshirt.IsRedshirt(target.Value) && mobStateComponent?.CurrentState == MobState.Dead; // DeltaV - Redshirt
var uncloneable = _uncloneable.IsUncloneable(target.Value) && mobStateComponent?.CurrentState == MobState.Dead; // DeltaV - Unclonable
// I'm just going to lump them all into 'extraTraitAlerts' to group our modifications as a single bool in the next check
var extraTraitAlerts = unborgable || redshirt || uncloneable;
// END DeltaV
var showAlerts = state.Unrevivable == true || state.Bleeding == true;
var showAlerts = state.Unrevivable == true || state.Bleeding == true || extraTraitAlerts; // DeltaV - extra alerts
AlertsDivider.Visible = showAlerts;
AlertsContainer.Visible = showAlerts;
@@ -32,10 +32,10 @@ namespace Content.Client.Labels.UI
}
_window.OnLabelChanged += OnLabelChanged;
_window.OnLabelSelected += OnLabelSelected; // Starlight
Reload();
_window.SetInitialLabelState(); // Must be after Reload() has set the label text
}
private void OnLabelChanged(string newLabel)
{
// Focus moment
@@ -45,7 +45,17 @@ namespace Content.Client.Labels.UI
SendPredictedMessage(new HandLabelerLabelChangedMessage(newLabel));
}
// Starlight start
private void OnLabelSelected(string label)
{
// Update UI and send message to sync with server
if (_window != null)
{
_window.SetCurrentLabel(label);
}
SendPredictedMessage(new HandLabelerLabelChangedMessage(label));
}
// Starlight End
public void Reload()
{
if (_window == null || !_entManager.TryGetComponent(Owner, out HandLabelerComponent? component))
@@ -1,8 +1,10 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
Title="{Loc 'hand-labeler-ui-header'}"
SetWidth="400"
MinWidth="150">
MinWidth="150"
SetHeight="400"> <!-- Starlight - include gfx and set default height to include saved labels section nicely -->
<BoxContainer Orientation="Vertical" SeparationOverride="4">
<Label Name="CurrentTextLabel" Text="{Loc 'hand-labeler-current-text-label'}" />
<LineEdit Name="LabelLineEdit" />
@@ -10,5 +12,19 @@
<Button Name="ResetLabelButton" Text="{Loc 'hand-labeler-ui-reset-label-text'}" StyleClasses="OpenRight" />
<Button Name="ClearLabelButton" Text="{Loc 'hand-labeler-ui-clear-label-text'}" StyleClasses="OpenLeft" />
</BoxContainer>
<!-- Starlight Begin -->
<Label Text="{Loc 'hand-labeler-saved-labels'}" />
<PanelContainer VerticalExpand="True" SizeFlagsStretchRatio="1">
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#1B1B1E" />
</PanelContainer.PanelOverride>
<ItemList Name="SavedLabelsList" VerticalExpand="True" SelectMode="Button" />
</PanelContainer>
<BoxContainer Orientation="Horizontal" Align="Center">
<Button Name="SaveLabelButton" Text="{Loc 'hand-labeler-save-label-text'}" StyleClasses="OpenRight" />
<Button Name="DeleteLabelButton" Text="{Loc 'hand-labeler-delete-label-text'}" StyleClasses="OpenLeft" />
</BoxContainer>
<!-- Starlight end -->
</BoxContainer>
</DefaultWindow>
@@ -1,13 +1,19 @@
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Robust.Client.UserInterface.Controls; // Starlight
using Robust.Shared.Configuration; // Starlight
using Content.Shared.Starlight.CCVar; // Starlight
namespace Content.Client.Labels.UI
{
[GenerateTypedNameReferences]
public sealed partial class HandLabelerWindow : DefaultWindow
{
[Dependency] private readonly IConfigurationManager _cfg = default!; // Starlight
public event Action<string>? OnLabelChanged;
public event Action<string>? OnLabelSelected; // Starlight
/// <summary>
/// Is the user currently entering text into the control?
@@ -17,10 +23,14 @@ namespace Content.Client.Labels.UI
private string _label = string.Empty;
private string _initialLabel = string.Empty;
private bool _deleteMode = false; // Starlight
private List<string> _savedLabels = []; // Starlight
public HandLabelerWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this); // Starlight
LoadSavedLabelsFromCVar(); // Starlight
LabelLineEdit.OnTextChanged += e =>
{
@@ -37,6 +47,42 @@ namespace Content.Client.Labels.UI
};
ResetLabelButton.OnPressed += _ => LabelLineEdit.SetText(_initialLabel, true);
ClearLabelButton.OnPressed += _ => LabelLineEdit.SetText("", true);
// Starlight Begin
SaveLabelButton.OnPressed += _ =>
{
if (!string.IsNullOrWhiteSpace(_label) && !_savedLabels.Contains(_label))
{
_savedLabels.Add(_label);
SaveSavedLabelsToCVar();
UpdateSavedLabels(_savedLabels);
}
};
DeleteLabelButton.OnPressed += _ =>
{
_deleteMode = !_deleteMode;
DeleteLabelButton.Pressed = _deleteMode;
UpdateButtons();
};
SavedLabelsList.OnItemSelected += args =>
{
if (_deleteMode)
{
_savedLabels.RemoveAt(args.ItemIndex);
SaveSavedLabelsToCVar();
UpdateSavedLabels(_savedLabels);
UpdateButtons();
}
else
{
if (SavedLabelsList[args.ItemIndex].Metadata is string label)
{
OnLabelSelected?.Invoke(label);
}
}
}; // Starlight End
}
protected override void Opened()
@@ -70,15 +116,68 @@ namespace Content.Client.Labels.UI
UpdateButtons();
}
// Starlight begin
public void UpdateSavedLabels(List<string> labels)
{
var items = new List<ItemList.Item>();
foreach (var label in labels)
{
var item = new ItemList.Item(SavedLabelsList)
{
Text = label,
Metadata = label
};
items.Add(item);
}
SavedLabelsList.SetItems(items);
UpdateButtons();
}
// Starlight end
public void UpdateButtons()
{
ResetLabelButton.Disabled = (LabelLineEdit.Text == _initialLabel);
ClearLabelButton.Disabled = (LabelLineEdit.Text == "");
}
// Starlight begin
var labelExists = false;
foreach (var item in SavedLabelsList)
{
if ((item.Metadata as string) == _label.Trim())
{
labelExists = true;
break;
}
}
SaveLabelButton.Disabled = string.IsNullOrWhiteSpace(_label) || labelExists;
DeleteLabelButton.Text = _deleteMode
? Loc.GetString("hand-labeler-delete-mode-text")
: Loc.GetString("hand-labeler-delete-label-text");
// Starlight end
}
public void SetMaxLabelLength(int maxLength)
{
LabelLineEdit.IsValid = s => s.Length <= maxLength;
}
// Starlight begin
private void LoadSavedLabelsFromCVar()
{
var savedLabelsStr = _cfg.GetCVar(StarlightCCVars.HandLabelerSavedLabels);
if (!string.IsNullOrEmpty(savedLabelsStr))
{
_savedLabels = new List<string>(savedLabelsStr.Split('\n', StringSplitOptions.RemoveEmptyEntries));
UpdateSavedLabels(_savedLabels);
}
}
private void SaveSavedLabelsToCVar()
{
var savedLabelsStr = string.Join('\n', _savedLabels);
_cfg.SetCVar(StarlightCCVars.HandLabelerSavedLabels, savedLabelsStr);
_cfg.SaveToFile();
}
// Starlight end
}
}
@@ -70,6 +70,11 @@ public sealed class ConfirmButton : Button
[ViewVariables]
public bool IsConfirming = false;
// Begin DeltaV
[ViewVariables]
public bool ForceDisabled = false;
// End DeltaV
public ConfirmButton()
{
IoCManager.InjectDependencies(this);
@@ -87,7 +92,7 @@ public sealed class ConfirmButton : Button
}
if (Disabled && _gameTiming.CurTime > _nextCooldown)
Disabled = false;
Disabled = ForceDisabled; // DeltaV
}
protected override void DrawModeChanged()
@@ -0,0 +1,30 @@
using Content.Shared._DV.Communications;
using Robust.Client.UserInterface;
namespace Content.Client._DV.Communications;
public sealed class DVCommunicationsConsoleBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IEntityManager _entity = default!;
private DVCommunicationsConsoleMenu? _menu;
public DVCommunicationsConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
protected override void Open()
{
base.Open();
_menu = this.CreateWindow<DVCommunicationsConsoleMenu>();
_menu.OnMessage += SendMessage;
if (_entity.TryGetComponent<DVCommunicationsConsoleComponent>(Owner, out var comp))
Update((Owner, comp));
}
public void Update(Entity<DVCommunicationsConsoleComponent> ent)
{
_menu?.Update(ent, PlayerManager.LocalEntity!.Value);
}
}
@@ -0,0 +1,117 @@
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'comms-console-menu-title'}"
MinSize="400 300">
<BoxContainer Name="HomeScreen" Orientation="Vertical" Margin="8">
<Label Text="{Loc 'comms-console-menu-station-title'}" Name="StationHeaderLabel" StyleClasses="LabelKeyText" />
<Button Name="AnnouncementTab" Text="{Loc 'comms-console-menu-tab.Announcement'}" />
<Button Name="ScreenTab" Text="{Loc 'comms-console-menu-tab.Screen'}" />
<Button Name="AlertLevelTab" Text="{Loc 'comms-console-menu-tab.AlertLevel'}" />
<Label Text="{Loc 'comms-console-menu-transit-title'}" Name="TransitHeaderLabel" StyleClasses="LabelKeyText" Margin="0 8 0 0" />
<Button Name="ShuttlesTab" Text="{Loc 'comms-console-menu-tab.Shuttles'}" />
<Label Text="{Loc 'comms-console-menu-emergency-title'}" Name="EmergencyHeaderLabel" StyleClasses="LabelKeyText" Margin="0 8 0 0" />
<Button Name="KeycardAuthenticationDeviceTab" Text="{Loc 'comms-console-menu-tab.KeycardAuthenticationDevice'}" />
</BoxContainer>
<BoxContainer Orientation="Vertical">
<Button Name="HomeButton" Text="{Loc 'comms-console-menu-home'}" Visible="False" />
<BoxContainer Name="AnnouncementScreen" Visible="False" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" SeparationOverride="8" Margin="8">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True" VerticalExpand="True">
<BoxContainer SeparationOverride="8" Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-announcement-text'}" StyleClasses="LabelKeyText" />
<TextEdit Name="AnnounceInput"
VerticalExpand="True"
HorizontalExpand="True"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
MinHeight="100" />
</BoxContainer>
</PanelContainer>
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True">
<Button Name="AnnounceButton" Margin="8" Text="{Loc 'comms-console-menu-send-announcement'}" />
</PanelContainer>
</BoxContainer>
<BoxContainer Name="ScreenScreen" Visible="False" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" SeparationOverride="8" Margin="8">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True">
<BoxContainer SeparationOverride="8" Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-screen-configuration'}" StyleClasses="LabelKeyText" />
<BoxContainer>
<Label Text="{Loc 'comms-console-menu-screen-contents'}" HorizontalExpand="True" />
<OptionButton Name="ScreenContentsButton" />
</BoxContainer>
<BoxContainer>
<Label Text="{Loc 'comms-console-menu-alert-level-border'}" HorizontalExpand="True" />
<Button Name="ScreenAlertBorder" Text="{Loc 'comms-console-menu-enable-border'}" ToggleMode="True" />
</BoxContainer>
</BoxContainer>
</PanelContainer>
<PanelContainer StyleClasses="PanelDark">
<BoxContainer Margin="8" Orientation="Vertical" SeparationOverride="4">
<Label Text="{Loc 'comms-console-menu-screen-text'}" StyleClasses="LabelKeyText" />
<GridContainer Columns="2" HorizontalExpand="True">
<Label Text="{Loc 'comms-console-menu-line-1'}" />
<LineEdit Name="ScreenLine1" HorizontalExpand="True" StyleClasses="comms-console-display" />
<Label Text="{Loc 'comms-console-menu-line-2'}" />
<LineEdit Name="ScreenLine2" HorizontalExpand="True" StyleClasses="comms-console-display" />
</GridContainer>
<Button Name="ScreenUpdateTextButton" Text="{Loc 'comms-console-menu-update-screen-text'}" HorizontalAlignment="Right" />
</BoxContainer>
</PanelContainer>
</BoxContainer>
<BoxContainer Name="ShuttlesScreen" Visible="False" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" SeparationOverride="8" Margin="8">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True">
<BoxContainer Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-emergency-shuttle'}" StyleClasses="LabelKeyText" />
<RichTextLabel Name="EmergencyStatus" Text="{Loc 'comms-console-menu-shuttle-not-coming'}" />
<Button Name="ShuttleEmergencyButton" Text="{Loc 'comms-console-menu-call-emergency.True'}" HorizontalAlignment="Right" Margin="0 8 0 0" />
</BoxContainer>
</PanelContainer>
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True">
<BoxContainer Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-exfiltration-shuttle'}" StyleClasses="LabelKeyText" />
<RichTextLabel Name="ExfiltrationStatus" Text="{Loc 'comms-console-menu-shuttle-not-coming'}" />
<Button Name="ShuttleExfiltrationButton" Text="{Loc 'comms-console-menu-call-exfiltration.True'}" HorizontalAlignment="Right" Margin="0 8 0 0" />
</BoxContainer>
</PanelContainer>
</BoxContainer>
<BoxContainer Name="AlertLevelScreen" Visible="False" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" SeparationOverride="8" Margin="8">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True" MaxWidth="400">
<BoxContainer Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-alert-level'}" StyleClasses="LabelKeyText" />
<RichTextLabel Name="AlertLevel" HorizontalExpand="True" />
<Button Name="AlertLevelsDropdown" Text="{Loc 'comms-console-menu-change-alert-level'}" HorizontalAlignment="Right" Margin="0 8 0 0" />
</BoxContainer>
</PanelContainer>
</BoxContainer>
<BoxContainer Name="KeycardAuthenticationDeviceScreen" Visible="False" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" SeparationOverride="8" Margin="8">
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True" MaxWidth="400">
<BoxContainer Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-declare-mayday.title'}" StyleClasses="LabelKeyText" />
<RichTextLabel Text="{Loc 'comms-console-menu-declare-mayday.desc'}" />
<controls:ConfirmButton Name="CallZeta" Text="{Loc 'comms-console-menu-declare-mayday.button'}" HorizontalAlignment="Stretch" Margin="0 8 0 0" />
</BoxContainer>
</PanelContainer>
<PanelContainer StyleClasses="PanelDark" HorizontalExpand="True" MaxWidth="400">
<BoxContainer Margin="8" HorizontalExpand="True" Orientation="Vertical">
<Label Text="{Loc 'comms-console-menu-request-codes.title'}" StyleClasses="LabelKeyText" />
<RichTextLabel Text="{Loc 'comms-console-menu-request-codes.desc'}" />
<controls:ConfirmButton Name="RequestCodes" Text="{Loc 'comms-console-menu-request-codes.button'}" HorizontalAlignment="Stretch" Margin="0 8 0 0" />
</BoxContainer>
</PanelContainer>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
@@ -0,0 +1,320 @@
using System.Globalization;
using System.Numerics;
using Content.Client.UserInterface.Controls;
using Content.Shared._DV.Communications;
using Content.Shared._DV.KeycardAuthenticationDevice;
using Content.Shared._DV.Screens;
using Content.Shared.Humanoid;
using Content.Shared.Station;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Content.Client._DV.Communications;
[GenerateTypedNameReferences]
public sealed partial class DVCommunicationsConsoleMenu : FancyWindow
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IEntityManager _entity = default!;
private readonly SharedStationSystem _station;
private readonly BoxContainer[] _screens;
private readonly ButtonGroup _group;
public event Action<BoundUserInterfaceMessage>? OnMessage;
private Entity<DVCommunicationsConsoleComponent>? _console;
private Entity<DVStationKeycardAuthenticationDeviceComponent>? _stationKeycardAuthenticationDevice;
private EntityUid? _user;
private readonly Popup _alertLevelsPopup;
private readonly BoxContainer _alertLevels = new()
{
Orientation = BoxContainer.LayoutOrientation.Vertical,
};
private string _lastConfiguredLine1 = string.Empty;
private string _lastConfiguredLine2 = string.Empty;
public DVCommunicationsConsoleMenu()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_station = _entity.System<SharedStationSystem>();
_group = new();
_screens = new[]
{
HomeScreen, AnnouncementScreen, ScreenScreen, ShuttlesScreen, AlertLevelScreen,
KeycardAuthenticationDeviceScreen,
};
HomeButton.OnPressed += _ => SetScreen(HomeScreen);
AnnouncementTab.OnPressed += _ => SetScreen(AnnouncementScreen);
ScreenTab.OnPressed += _ => SetScreen(ScreenScreen);
ShuttlesTab.OnPressed += _ => SetScreen(ShuttlesScreen);
AlertLevelTab.OnPressed += _ => SetScreen(AlertLevelScreen);
KeycardAuthenticationDeviceTab.OnPressed += _ => SetScreen(KeycardAuthenticationDeviceScreen);
foreach (var value in Enum.GetValues<DVScreenContent>())
{
ScreenContentsButton.AddItem(Loc.GetString($"comms-console-menu-screen-content.{value}"), (int)value);
}
AnnounceButton.OnPressed += OnAnnouncePressed;
ScreenUpdateTextButton.OnPressed += OnUpdateScreenText;
ScreenContentsButton.OnItemSelected += OnScreenContentsSelected;
ScreenAlertBorder.OnToggled += OnScreenAlertBorderToggled;
ShuttleEmergencyButton.OnPressed += OnEmergencyPressed;
ShuttleExfiltrationButton.OnPressed += OnExfiltrationPressed;
AlertLevelsDropdown.OnPressed += OnAlertLevelsDropdownPressed;
CallZeta.OnPressed += OnCallZetaPressed;
RequestCodes.OnPressed += OnRequestCodesPressed;
_alertLevelsPopup = new()
{
Children = { _alertLevels },
};
_alertLevelsPopup.OnPopupHide += () => _alertLevelsPopup.Orphan();
AnnounceInput.Placeholder = new Rope.Leaf(Loc.GetString("comms-console-menu-announcement-placeholder"));
}
private void OnAlertLevelsDropdownPressed(BaseButton.ButtonEventArgs args)
{
var globalPos = AlertLevelsDropdown.GlobalPosition;
globalPos.Y += AlertLevelsDropdown.Size.Y + 1; // Place it below us, with a safety margin.
_alertLevels.Measure(Window?.Size ?? Vector2Helpers.Infinity);
var (minX, minY) = _alertLevels.DesiredSize;
var box = UIBox2.FromDimensions(globalPos, new Vector2(Math.Max(minX, AlertLevelsDropdown.Width), minY));
_alertLevelsPopup.Orphan();
Root?.ModalRoot.AddChild(_alertLevelsPopup);
_alertLevelsPopup.Open(box);
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if (_console is not { } console)
return;
AnnounceButton.Disabled = _timing.CurTime <= console.Comp.CanAnnounceAt;
AlertLevelsDropdown.Disabled = console.Comp.CanSetAlertAt is null || _timing.CurTime <= console.Comp.CanSetAlertAt;
if (AlertLevelsDropdown.Disabled)
_alertLevelsPopup.Close();
if (console.Comp.ExpectedEvacuationArrival is { } evacArrival)
{
var diff = MathHelper.Max(evacArrival - _timing.CurTime, TimeSpan.Zero);
var infoText = Loc.GetString($"comms-console-menu-shuttle-eta",
("time", diff.ToString(@"hh\:mm\:ss", CultureInfo.CurrentCulture)));
EmergencyStatus.Text = infoText;
}
else
{
EmergencyStatus.Text = Loc.GetString("comms-console-menu-shuttle-not-coming");
}
if (console.Comp.ExpectedExfiltrationArrival is { } exfiltrationArrival)
{
var diff = MathHelper.Max(exfiltrationArrival - _timing.CurTime, TimeSpan.Zero);
var infoText = Loc.GetString($"comms-console-menu-shuttle-eta",
("time", diff.ToString(@"hh\:mm\:ss", CultureInfo.CurrentCulture)));
ExfiltrationStatus.Text = infoText;
}
else
{
ExfiltrationStatus.Text = Loc.GetString("comms-console-menu-shuttle-not-coming");
}
UpdateKeycardAuthenticationDevice();
}
private void SetScreen(Control screen)
{
foreach (var other in _screens)
{
other.Visible = false;
}
screen.Visible = true;
HomeButton.Visible = screen != HomeScreen;
}
public void Update(Entity<DVCommunicationsConsoleComponent> console, EntityUid user)
{
_console = console;
_user = user;
if (_station.GetOwningStation(console) is { } station &&
_entity.TryGetComponent<DVStationKeycardAuthenticationDeviceComponent>(station,
out var keycardAuthenticationDevice))
{
_stationKeycardAuthenticationDevice = (station, keycardAuthenticationDevice);
}
// If they only have the ability to announce, there's no point in having a home button
if (console.Comp.CanAnnounce && !(console.Comp.CanAlertLevel || console.Comp.CanCallShuttles || console.Comp.CanConfigureScreens || console.Comp.CanKeycardAuthenticationDevice))
{
SetScreen(AnnouncementScreen);
HomeButton.Visible = false;
}
// Station
StationHeaderLabel.Visible = console.Comp.CanAnnounce || console.Comp.CanConfigureScreens || console.Comp.CanAlertLevel;
AnnouncementTab.Visible = console.Comp.CanAnnounce;
ScreenTab.Visible = console.Comp.CanConfigureScreens;
AlertLevelTab.Visible = console.Comp.CanAlertLevel;
// Shuttles
TransitHeaderLabel.Visible = console.Comp.CanCallShuttles; // Should be only hidden if all buttons under are also hidden.
ShuttlesTab.Visible = console.Comp.CanCallShuttles;
// Emergency
EmergencyHeaderLabel.Visible = console.Comp.CanKeycardAuthenticationDevice; // Should be only hidden if all buttons under are also hidden.
KeycardAuthenticationDeviceTab.Visible = console.Comp.CanKeycardAuthenticationDevice;
ShuttleEmergencyButton.Disabled = !console.Comp.ShuttlesCallable;
ShuttleExfiltrationButton.Disabled = !console.Comp.ShuttlesCallable;
ShuttleEmergencyButton.Text =
Loc.GetString($"comms-console-menu-call-emergency.{console.Comp.ExpectedEvacuationArrival is null}");
ShuttleExfiltrationButton.Text =
Loc.GetString($"comms-console-menu-call-exfiltration.{console.Comp.ExpectedExfiltrationArrival is null}");
_alertLevels.RemoveAllChildren();
foreach (var level in console.Comp.AlertLevels)
{
if (level.Id == console.Comp.CurrentAlertLevel)
{
AlertLevel.Text = Loc.GetString("comms-console-menu-current-alert-level",
("name", Loc.GetString(level.AlertLevel)),
("color", level.Color),
("description", Loc.GetString(level.Description)));
}
if (!level.CanSet)
continue;
var btn = new Button
{
Text = Loc.GetString(level.AlertLevel),
ToggleMode = true,
Group = _group,
Pressed = level.Id == console.Comp.CurrentAlertLevel,
};
_alertLevels.AddChild(btn);
btn.OnPressed += _ =>
{
_alertLevelsPopup.Close();
OnMessage?.Invoke(new DVCommunicationsConsoleAlertLevelMessage(level.Id));
};
}
if (console.Comp.LastConfiguredLine1 != _lastConfiguredLine1)
ScreenLine1.Text = console.Comp.LastConfiguredLine1;
if (console.Comp.LastConfiguredLine2 != _lastConfiguredLine2)
ScreenLine2.Text = console.Comp.LastConfiguredLine2;
ScreenContentsButton.SelectId((int)console.Comp.LastConfiguredContent);
ScreenAlertBorder.Pressed = console.Comp.LastConfiguredShowBorders;
_lastConfiguredLine1 = console.Comp.LastConfiguredLine1;
_lastConfiguredLine2 = console.Comp.LastConfiguredLine2;
UpdateKeycardAuthenticationDevice();
}
private void UpdateKeycardAuthenticationDevice()
{
if (_user is not { } user || _stationKeycardAuthenticationDevice is not { } station)
return;
var canCall = !_entity.HasComponent<DVStationKeycardAuthenticationDeviceAlreadySwipedComponent>(user)
&& _entity.HasComponent<HumanoidProfileComponent>(user) // Can't be AI or a borg
&& station.Comp.AccessibleAfter <= _timing.CurTime;
CallZeta.ForceDisabled = !(canCall && station.Comp.SwipingFor is null or DVStationKeycardAction.Mayday);
CallZeta.Disabled = CallZeta.ForceDisabled;
RequestCodes.ForceDisabled = !(canCall && station.Comp.SwipingFor is null or DVStationKeycardAction.Scuttling);
RequestCodes.Disabled = RequestCodes.ForceDisabled;
if (CallZeta.IsConfirming || RequestCodes.IsConfirming)
return;
// Kinda messy but it works
if (station.Comp.SwipesStartedAt is { } firstSwipeTime)
{
var countdown = firstSwipeTime + station.Comp.SwipeWindow;
var timeRemaining = countdown.Subtract(_timing.CurTime);
if (timeRemaining > TimeSpan.Zero && station.Comp.SwipingFor is DVStationKeycardAction.Mayday)
CallZeta.Text = $"{timeRemaining:ss\\.fff}";
if (timeRemaining > TimeSpan.Zero && station.Comp.SwipingFor is DVStationKeycardAction.Scuttling)
RequestCodes.Text = $"{timeRemaining:ss\\.fff}";
}
else
{
CallZeta.Text = Loc.GetString("comms-console-menu-declare-mayday.button");
RequestCodes.Text = Loc.GetString("comms-console-menu-request-codes.button");
}
}
private void OnAnnouncePressed(BaseButton.ButtonEventArgs args)
{
OnMessage?.Invoke(new DVCommunicationsConsoleAnnouncementMessage(Rope.Collapse(AnnounceInput.TextRope)));
}
private void UpdateScreens()
{
OnMessage?.Invoke(new DVCommunicationsConsoleScreenConfigurationMessage(
(DVScreenContent) ScreenContentsButton.SelectedId,
ScreenAlertBorder.Pressed,
ScreenLine1.Text,
ScreenLine2.Text));
}
private void OnUpdateScreenText(BaseButton.ButtonEventArgs buttonEventArgs)
{
UpdateScreens();
}
private void OnScreenContentsSelected(OptionButton.ItemSelectedEventArgs itemSelectedEventArgs)
{
ScreenContentsButton.SelectId(itemSelectedEventArgs.Id);
UpdateScreens();
}
private void OnScreenAlertBorderToggled(BaseButton.ButtonToggledEventArgs buttonToggledEventArgs)
{
UpdateScreens();
}
private void OnExfiltrationPressed(BaseButton.ButtonEventArgs args)
{
OnMessage?.Invoke(new DVCommunicationsConsoleExfiltrationShuttleMessage(_console?.Comp.ExpectedExfiltrationArrival is null));
}
private void OnEmergencyPressed(BaseButton.ButtonEventArgs args)
{
OnMessage?.Invoke(new DVCommunicationsConsoleEvacuationShuttleMessage(_console?.Comp.ExpectedEvacuationArrival is null));
}
private void OnCallZetaPressed(BaseButton.ButtonEventArgs obj)
{
OnMessage?.Invoke(new DVCommunicationsConsoleKeycardAuthenticationDeviceMessage(DVStationKeycardAction.Mayday));
}
private void OnRequestCodesPressed(BaseButton.ButtonEventArgs obj)
{
OnMessage?.Invoke(new DVCommunicationsConsoleKeycardAuthenticationDeviceMessage(DVStationKeycardAction.Scuttling));
}
}
@@ -0,0 +1,26 @@
using Content.Shared._DV.Communications;
using Robust.Client.GameObjects;
namespace Content.Client._DV.Communications;
public sealed class DVCommunicationsConsoleSystem : SharedDVCommunicationsConsoleSystem
{
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVCommunicationsConsoleComponent, AfterAutoHandleStateEvent>(OnHandleState);
}
private void OnHandleState(Entity<DVCommunicationsConsoleComponent> ent, ref AfterAutoHandleStateEvent args)
{
if (!_userInterface.TryGetOpenUi<DVCommunicationsConsoleBoundUserInterface>(ent.Owner,
DVCommunicationsConsoleUi.Key,
out var bui))
return;
bui.Update(ent);
}
}
@@ -0,0 +1,5 @@
using Content.Shared._DV.KeycardAuthenticationDevice;
namespace Content.Client._DV.KeycardAuthenticationDevice;
public sealed class DVStationKeycardAuthenticationDeviceSystem : SharedDVStationKeycardAuthenticationDeviceSystem;
@@ -0,0 +1,103 @@
using System.Globalization;
using Content.Client.GameTicking.Managers;
using Content.Client.Interactable.Components;
using Content.Client.TextScreen;
using Content.Shared._DV.Screens;
using Robust.Shared.Timing;
namespace Content.Client._DV.Screens;
public sealed class DVScreenSystem : DVSharedScreenSystem
{
[Dependency] private readonly DVTextVisualsSystem _textVisuals = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly ClientGameTicker _ticker = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVScreenComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<DVScreenComponent, AfterAutoHandleStateEvent>(OnScreenState);
}
public override void FrameUpdate(float frameTime)
{
base.FrameUpdate(frameTime);
var query = EntityQueryEnumerator<DVScreenComponent>();
while (query.MoveNext(out var uid, out var screen))
{
switch (screen.Content)
{
case DVScreenContent.Text:
break;
case DVScreenContent.CurrentTime:
CurrentTime((uid, screen));
break;
case DVScreenContent.EstimatedTimeOfArrival:
EstimatedTimeOfArrival((uid, screen));
break;
case DVScreenContent.AlertLevel:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
private void OnInit(Entity<DVScreenComponent> ent, ref ComponentInit args)
{
// Remove interaction outline because it outlines the offscreen text and looks bad
RemComp<InteractionOutlineComponent>(ent);
}
private void OnScreenState(Entity<DVScreenComponent> ent, ref AfterAutoHandleStateEvent args)
{
UpdateVisuals(ent);
switch (ent.Comp.Content)
{
case DVScreenContent.Text:
Text(ent);
break;
case DVScreenContent.CurrentTime:
CurrentTime(ent);
break;
case DVScreenContent.EstimatedTimeOfArrival:
EstimatedTimeOfArrival(ent);
break;
case DVScreenContent.AlertLevel:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private void Text(Entity<DVScreenComponent> ent)
{
_textVisuals.SetText(ent.Owner, ent.Comp.Line1, ent.Comp.Line2);
}
private void CurrentTime(Entity<DVScreenComponent> ent)
{
var time = (_timing.CurTime - _ticker.RoundStartTimeSpan).Duration();
_textVisuals.SetText(ent.Owner, Loc.GetString("status-display-time"), time.ToString("hh\\:mm"));
}
private void EstimatedTimeOfArrival(Entity<DVScreenComponent> ent)
{
if (ent.Comp.TargetTime <= _timing.CurTime)
{
_textVisuals.SetText(ent.Owner, string.Empty, string.Empty);
return;
}
var time = (_timing.CurTime - ent.Comp.TargetTime).Duration();
var formatted = time.ToString("mm\\:ss");
Log.Debug($"{_timing.CurTime} - {ent.Comp.TargetTime} = {time}");
var title = ent.Comp.ScreenIsAtDestination ? Loc.GetString("status-display-etd") : Loc.GetString("status-display-eta");
_textVisuals.SetText(ent.Owner, title, formatted);
}
}
@@ -0,0 +1,140 @@
using System.Linq;
using System.Numerics;
using System.Threading;
using JetBrains.Annotations;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.Enums;
namespace Content.Client._DV.Screens;
[UsedImplicitly]
public sealed class DVTextRenderingOverlay : Overlay
{
[Dependency] private readonly IClyde _clyde = default!;
private readonly SpriteSystem _sprite;
private readonly AnimationPlayerSystem _animationPlayer;
public override OverlaySpace Space => OverlaySpace.ScreenSpaceBelowWorld;
private readonly Queue<(Entity<DVTextVisualsComponent> Entity, Font Font, CancellationToken Cancellation)> _queue = new();
public const string MarqueeKey = "dv-text-screen-marquee";
public DVTextRenderingOverlay(SpriteSystem sprite, AnimationPlayerSystem animationPlayer)
{
IoCManager.InjectDependencies(this);
_sprite = sprite;
_animationPlayer = animationPlayer;
ZIndex = -100; // this needs to render before almost everything
}
public CancellationTokenSource QueueRender(
Entity<DVTextVisualsComponent> ent,
Font font)
{
var source = new CancellationTokenSource();
_queue.Enqueue((ent, font, source.Token));
return source;
}
protected override void Draw(in OverlayDrawArgs args)
{
var screenHandle = args.ScreenHandle;
while (_queue.TryDequeue(out var queued))
{
if (queued.Cancellation.IsCancellationRequested)
continue;
var font = queued.Font;
foreach (var row in queued.Entity.Comp.Rows)
{
if (row.Text == string.Empty)
{
_sprite.LayerSetTexture(queued.Entity.Owner, row.Layer, null);
continue;
}
var dimensions = screenHandle.GetDimensions(queued.Font, row.Text, 1f);
var dimensionsInt = new Vector2i((int)MathF.Round(dimensions.X), (int)MathF.Round(dimensions.Y));
if (row.Texture is null || row.Texture.Size != dimensionsInt)
{
row.Texture = _clyde.CreateRenderTarget(dimensionsInt,
new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8),
name: $"dv-text-visuals-{queued.Entity.Owner.Id}");
_sprite.LayerSetTexture(queued.Entity.Owner, row.Layer, row.Texture.Texture);
_sprite.LayerSetOffset(queued.Entity.Owner, row.Layer, row.Offset);
}
args.DrawingHandle.RenderInRenderTarget(row.Texture,
() =>
{
screenHandle.DrawString(font, Vector2.Zero, row.Text);
},
Color.Transparent);
}
_animationPlayer.Stop(queued.Entity.Owner, MarqueeKey);
if (CreateMarqueeAnimation(queued.Entity) is { } animation)
{
queued.Entity.Comp.Animation = animation;
_animationPlayer.Play(queued.Entity.Owner, animation, MarqueeKey);
}
}
}
private Animation? CreateMarqueeAnimation(Entity<DVTextVisualsComponent> ent)
{
var largestRowWidth = ent.Comp.Rows.Aggregate(0, (i, row) => Math.Max(i, row.Texture?.Size.X ?? 0));
var animationTime = ent.Comp.MarqueeRate * largestRowWidth;
var marqueeWidth = new Vector2((float)ent.Comp.MarqueeWidth / EyeManager.PixelsPerMeter, 0);
var animation = new Animation
{
Length = animationTime,
};
foreach (var row in ent.Comp.Rows)
{
if (row.Texture is null)
continue;
var rowHalfWidth = new Vector2(row.Texture.Size.X / 2f / EyeManager.PixelsPerMeter, 0f);
if (row.Texture.Size.X <= ent.Comp.MarqueeWidth)
continue;
animation.AnimationTracks.Add(new AnimationTrackLayerOffset()
{
Layer = row.Layer,
KeyFrames =
{
new AnimationTrackProperty.KeyFrame(row.Offset + rowHalfWidth + marqueeWidth, 0f),
new AnimationTrackProperty.KeyFrame(row.Offset - rowHalfWidth - marqueeWidth, (float)animationTime.TotalSeconds),
},
});
}
return animation.AnimationTracks.Count > 0 ? animation : null;
}
public sealed class AnimationTrackLayerOffset : AnimationTrackProperty
{
public required Enum Layer;
private readonly SpriteSystem _sprite = IoCManager.Resolve<IEntityManager>().System<SpriteSystem>();
protected override void ApplyProperty(object context, object value)
{
if (value is not Vector2 vector)
throw new InvalidOperationException("Value must be a .");
_sprite.LayerSetOffset((EntityUid) context, Layer, vector);
}
}
}
@@ -0,0 +1,43 @@
using System.Numerics;
using System.Threading;
using Content.Shared._DV.Screens;
using Robust.Client.Animations;
using Robust.Client.Graphics;
namespace Content.Client._DV.Screens;
[RegisterComponent]
[Access(typeof(DVTextVisualsSystem), typeof(DVTextRenderingOverlay))]
public sealed partial class DVTextVisualsComponent : Component
{
[DataField(required: true)]
public List<DVTextVisualsRow> Rows;
[DataField]
public TimeSpan MarqueeRate = TimeSpan.FromSeconds(0.045f);
[DataField]
public int MarqueeWidth = 24;
[DataField]
public int MarqueePadding = 8;
public Animation? Animation;
public CancellationTokenSource? Token;
}
[DataDefinition]
public sealed partial class DVTextVisualsRow
{
public IRenderTexture? Texture;
[DataField]
public string Text;
[DataField]
public Vector2 Offset;
[DataField(required: true)]
public Enum Layer = DVTextScreenVisualLayers.Line1;
}
@@ -0,0 +1,73 @@
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
namespace Content.Client._DV.Screens;
public sealed class DVTextVisualsSystem : EntitySystem
{
[Dependency] private readonly IOverlayManager _overlay = default!;
[Dependency] private readonly IResourceCache _resource = default!;
[Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
private DVTextRenderingOverlay _textRendering = default!;
private Font _font = default!;
public override void Initialize()
{
base.Initialize();
_textRendering = new(_sprite, _animationPlayer);
_overlay.AddOverlay(_textRendering);
_font = new VectorFont(_resource.GetResource<FontResource>("/Fonts/_DV/TinyUnicode.ttf"), 12);
SubscribeLocalEvent<DVTextVisualsComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<DVTextVisualsComponent, ComponentShutdown>(OnComponentShutdown);
SubscribeLocalEvent<DVTextVisualsComponent, AnimationCompletedEvent>(OnAnimationComplete);
}
public override void Shutdown()
{
_overlay.RemoveOverlay(_textRendering);
}
private void OnComponentInit(Entity<DVTextVisualsComponent> ent, ref ComponentInit args)
{
ent.Comp.Token = _textRendering.QueueRender(ent, _font);
}
private void OnComponentShutdown(Entity<DVTextVisualsComponent> ent, ref ComponentShutdown args)
{
foreach (var row in ent.Comp.Rows)
{
row.Texture?.Dispose();
}
ent.Comp.Token?.Cancel();
}
private void OnAnimationComplete(Entity<DVTextVisualsComponent> ent, ref AnimationCompletedEvent args)
{
if (args.Key != DVTextRenderingOverlay.MarqueeKey || !args.Finished || ent.Comp.Animation is not { } animation)
return;
_animationPlayer.Play(ent.Owner, animation, DVTextRenderingOverlay.MarqueeKey);
}
public void SetText(Entity<DVTextVisualsComponent?> ent, params string[] rows)
{
if (!Resolve(ent, ref ent.Comp))
return;
var count = Math.Min(rows.Length, ent.Comp.Rows.Count);
for (var i = 0; i < count; i++)
{
ent.Comp.Rows[i].Text = rows[i];
}
ent.Comp.Token?.Cancel();
ent.Comp.Token = _textRendering.QueueRender((ent, ent.Comp), _font);
}
}
@@ -0,0 +1,23 @@
using Content.Client.Resources;
using Content.Client.Stylesheets;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using static Content.Client.Stylesheets.StylesheetHelpers;
namespace Content.Client._DV.Stylesheets.Sheetlets;
[CommonSheetlet]
public sealed class DVLineEditSheetlet : Sheetlet<PalettedStylesheet>
{
public override StyleRule[] GetRules(PalettedStylesheet sheet, object config)
{
var tinyUnicode = ResCache.GetFont("/Fonts/_DV/TinyUnicode.ttf", size: 24);
return
[
E<LineEdit>()
.Class("comms-console-display")
.Font(tinyUnicode),
];
}
}
@@ -1,6 +1,7 @@
using Content.Server.Chat.Systems;
using Content.Server.GameTicking;
using Content.Server.Ninja.Systems;
using Content.Shared._DV.Communications; // DeltaV Comms Console
using Content.Shared.Communications;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
@@ -35,7 +36,7 @@ public sealed class CommsHackerSystem : SharedCommsHackerSystem
/// </summary>
private void OnBeforeInteractHand(EntityUid uid, CommsHackerComponent comp, BeforeInteractHandEvent args)
{
if (args.Handled || !HasComp<CommunicationsConsoleComponent>(args.Target))
if (args.Handled || !HasComp<DVCommunicationsConsoleComponent>(args.Target)) // DeltaV - Comms Console
return;
// TODO: generic check event
@@ -23,7 +23,7 @@ using Robust.Shared.Configuration;
namespace Content.Server.Communications
{
public sealed partial class CommunicationsConsoleSystem : EntitySystem // DeltaV - Partial Class
public sealed class CommunicationsConsoleSystem : EntitySystem
{
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
[Dependency] private readonly AlertLevelSystem _alertLevelSystem = default!;
@@ -53,8 +53,6 @@ namespace Content.Server.Communications
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleCallEmergencyShuttleMessage>(OnCallShuttleMessage);
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleRecallEmergencyShuttleMessage>(OnRecallShuttleMessage);
InitializeExfiltration(); // DeltaV - Exfiltration shuttle
// On console init, set cooldown
SubscribeLocalEvent<CommunicationsConsoleComponent, MapInitEvent>(OnCommunicationsConsoleMapInit);
}
@@ -138,7 +136,6 @@ namespace Content.Server.Communications
List<string>? levels = null;
string currentLevel = default!;
float currentDelay = 0;
TimeSpan? exfiltrationTime = null; // DeltaV - exfiltration shuttle
if (stationUid != null)
{
@@ -160,12 +157,6 @@ namespace Content.Server.Communications
currentLevel = alertComp.CurrentLevel;
currentDelay = _alertLevelSystem.GetAlertLevelDelay(stationUid.Value, alertComp);
}
// Begin DeltaV - exfiltration shuttle
if (TryComp<StationExfiltrationComponent>(stationUid, out var exfiltration))
{
exfiltrationTime = exfiltration.ArrivalTime;
}
// End DeltaV - exfiltration shuttle
}
_uiSystem.SetUiState(uid, CommunicationsConsoleUiKey.Key, new CommunicationsConsoleInterfaceState(
@@ -174,8 +165,7 @@ namespace Content.Server.Communications
levels,
currentLevel,
currentDelay,
_roundEndSystem.ExpectedCountdownEnd,
exfiltrationTime // DeltaV - exfiltration shuttle
_roundEndSystem.ExpectedCountdownEnd
));
}
@@ -30,6 +30,17 @@ public sealed partial class EmergencyLightComponent : SharedEmergencyLightCompon
[DataField("chargingEfficiency")]
public float ChargingEfficiency = 0.85f;
// Begin DeltaV Additions
[DataField]
public float MaydayRadius = 10f;
[DataField]
public float MaydayFalloff = 0f;
[DataField]
public float MaydayEnergy = 0.7f;
// End DeltaV Additions
public Dictionary<EmergencyLightState, string> BatteryStateText = new()
{
{ EmergencyLightState.Full, "emergency-light-component-light-state-full" },
@@ -85,11 +85,11 @@ public sealed partial class HealthAnalyzerSystem : EntitySystem // DeltaV - Made
if (component.MaxScanRange != null && !_transformSystem.InRange(patientCoordinates, transform.Coordinates, component.MaxScanRange.Value))
{
//Range too far, disable updates
PauseAnalyzingEntity((uid, component), patient); // DeltaV - Analyzer Reactivation
PauseAnalyzingEntity((uid, component), patient);
continue;
}
component.IsAnalyzerActive = true; // DeltaV - Analyzer Reactivation
component.IsAnalyzerActive = true;
UpdateScannedUser(uid, patient, true);
}
}
@@ -197,7 +197,7 @@ public sealed partial class HealthAnalyzerSystem : EntitySystem // DeltaV - Made
}
/// <summary>
/// DeltaV - If the scanner is active, sends one last update and sets it to inactive.
/// If the scanner is active, sends one last update and sets it to inactive.
/// </summary>
/// <param name="healthAnalyzer">The health analyzer that's receiving the updates</param>
/// <param name="target">The entity to analyze</param>
@@ -22,6 +22,7 @@ using Content.Shared.StatusEffect;
using Content.Shared.Store.Components;
using Content.Shared.Stunnable;
using Content.Shared.Tag;
using Content.Shared.Weapons.Melee.Events; // DeltaV
using Robust.Server.GameObjects;
using Robust.Shared.Physics.Components;
using Robust.Shared.Prototypes;
@@ -64,6 +65,7 @@ public sealed partial class RevenantSystem : EntitySystem
SubscribeLocalEvent<RevenantComponent, StatusEffectAddedEvent>(OnStatusAdded);
SubscribeLocalEvent<RevenantComponent, StatusEffectEndedEvent>(OnStatusEnded);
SubscribeLocalEvent<RoundEndTextAppendEvent>(_ => MakeVisible(true));
SubscribeLocalEvent<RevenantComponent, MeleeAttackEvent>(OnMeleeAttack); // DeltaV
SubscribeLocalEvent<RevenantComponent, GetVisMaskEvent>(OnRevenantGetVis);
@@ -131,6 +133,14 @@ public sealed partial class RevenantSystem : EntitySystem
ChangeEssenceAmount(uid, essenceDamage, component);
}
/// <summary>
/// DeltaV - No more attack spam and remaining invisible
/// </summary>
private void OnMeleeAttack(Entity<RevenantComponent> ent, ref MeleeAttackEvent args)
{
_statusEffects.TryAddStatusEffect<CorporealComponent>(ent, "Corporeal", ent.Comp.MeleeRevealTime, false);
}
public bool ChangeEssenceAmount(EntityUid uid, FixedPoint2 amount, RevenantComponent? component = null, bool allowDeath = true, bool regenCap = false)
{
if (!Resolve(uid, ref component))
@@ -1,32 +0,0 @@
using Content.Server._DV.Station.Components;
using Content.Server._DV.Station.Systems;
using Content.Shared._DV.Communications;
namespace Content.Server.Communications;
public sealed partial class CommunicationsConsoleSystem : EntitySystem
{
[Dependency] private readonly StationExfiltrationSystem _stationExfiltration = default!;
private void InitializeExfiltration()
{
SubscribeLocalEvent<CommunicationsConsoleComponent, CommunicationsConsoleExfiltrationShuttleMessage>(OnExfiltrationMessage);
}
private void OnExfiltrationMessage(Entity<CommunicationsConsoleComponent> ent, ref CommunicationsConsoleExfiltrationShuttleMessage args)
{
if (_stationSystem.GetOwningStation(ent) is not { } station)
return;
if (!CanUse(args.Actor, ent))
{
_popupSystem.PopupEntity(Loc.GetString("comms-console-permission-denied"), ent, args.Actor);
return;
}
if (args.Call)
_stationExfiltration.Call(station);
else
_stationExfiltration.Recall(station);
}
}
@@ -0,0 +1,184 @@
using Content.Server._DV.Station.Components;
using Content.Server._DV.Station.Systems;
using Content.Server.AlertLevel;
using Content.Server.Communications;
using Content.Server.RoundEnd;
using Content.Server.Shuttles.Systems;
using Content.Shared._DV.Communications;
using Content.Shared.CCVar;
using Content.Shared.Database;
using Content.Shared.Station;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
namespace Content.Server._DV.Communications;
public sealed class DVCommunicationsConsoleSystem : SharedDVCommunicationsConsoleSystem
{
[Dependency] private readonly SharedStationSystem _station = default!;
[Dependency] private readonly EmergencyShuttleSystem _emergencyShuttle = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly RoundEndSystem _roundEnd = default!;
[Dependency] private readonly IConfigurationManager _configuration = default!;
[Dependency] private readonly AlertLevelSystem _alertLevel = default!;
[Dependency] private readonly StationExfiltrationSystem _stationExfiltration = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RoundEndSystemChangedEvent>(OnRoundEndChanged);
SubscribeLocalEvent<StationExfiltrationChangedEvent>(OnExfiltrationChanged);
SubscribeLocalEvent<AlertLevelChangedEvent>(OnAlertLevelChanged);
}
private void OnAlertLevelChanged(AlertLevelChangedEvent ev)
{
var query = EntityQueryEnumerator<DVCommunicationsConsoleComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (_station.GetOwningStation(uid) != ev.Station)
continue;
var alertLevel = Comp<AlertLevelComponent>(ev.Station);
comp.CanSetAlertAt = Timing.CurTime + TimeSpan.FromSeconds(alertLevel.CurrentDelay);
comp.CurrentAlertLevel = ev.AlertLevel;
if (alertLevel.IsLevelLocked)
comp.CanSetAlertAt = null;
Dirty(uid, comp);
}
}
private void OnExfiltrationChanged(ref StationExfiltrationChangedEvent ev)
{
var query = EntityQueryEnumerator<DVCommunicationsConsoleComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (_station.GetOwningStation(uid) != ev.Station)
continue;
comp.ExpectedExfiltrationArrival = ev.Station.Comp.ArrivalTime;
Dirty(uid, comp);
}
}
private void OnRoundEndChanged(RoundEndSystemChangedEvent ev)
{
var query = EntityQueryEnumerator<DVCommunicationsConsoleComponent>();
while (query.MoveNext(out var uid, out var comp))
{
comp.ExpectedEvacuationArrival = _roundEnd.ExpectedCountdownEnd;
comp.ExpectedEvacuationDuration = _roundEnd.ExpectedShuttleLength;
comp.ShuttlesCallable = ShuttlesCallable();
Dirty(uid, comp);
}
}
protected override void OnMapInit(Entity<DVCommunicationsConsoleComponent> ent, ref MapInitEvent args)
{
base.OnMapInit(ent, ref args);
if (_station.GetOwningStation(ent) is not { } station)
return;
if (!TryComp<AlertLevelComponent>(station, out var alertLevel))
return;
ent.Comp.CurrentAlertLevel = alertLevel.CurrentLevel;
var proto = _prototype.Index<AlertLevelPrototype>(alertLevel.AlertLevelPrototype);
foreach (var (name, detail) in proto.Levels)
{
ent.Comp.AlertLevels.Add(new($"alert-level-{name}", $"alert-level-{name}-announcement", name, !detail.DisableSelection, detail.Color));
}
ent.Comp.CanSetAlertAt = Timing.CurTime + TimeSpan.FromSeconds(alertLevel.CurrentDelay);
if (alertLevel.IsLevelLocked)
ent.Comp.CanSetAlertAt = null;
ent.Comp.ShuttlesCallable = ShuttlesCallable();
ent.Comp.ExpectedEvacuationArrival = _roundEnd.ExpectedCountdownEnd;
ent.Comp.ExpectedEvacuationDuration = _roundEnd.ExpectedShuttleLength;
if (TryComp<StationExfiltrationComponent>(station, out var exfiltration))
ent.Comp.ExpectedExfiltrationArrival = exfiltration.ArrivalTime;
Dirty(ent);
}
private bool ShuttlesCallable()
{
// Defer to what the round end system thinks we should be able to do.
if (_emergencyShuttle.EmergencyShuttleArrived || !_roundEnd.CanCallOrRecall())
return false;
// Calling shuttle checks
if (_roundEnd.ExpectedCountdownEnd is null)
return true;
// Recalling shuttle checks
var recallThreshold = _configuration.GetCVar(CCVars.EmergencyRecallTurningPoint);
// shouldn't really be happening if we got here
if (_roundEnd.ShuttleTimeLeft is not { } left
|| _roundEnd.ExpectedShuttleLength is not { } expected)
return false;
return !(left.TotalSeconds / expected.TotalSeconds < recallThreshold);
}
protected override void OnAlertLevel(Entity<DVCommunicationsConsoleComponent> ent, ref DVCommunicationsConsoleAlertLevelMessage args)
{
base.OnAlertLevel(ent, ref args);
if (!AccessReader.IsAllowed(ent, args.Actor))
return;
if (_station.GetOwningStation(ent) is not { } station)
return;
_alertLevel.SetLevel(station, args.AlertLevel, true, true);
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Actor):player} has set the alert level to {args.AlertLevel:level} on {ToPrettyString(station):station} using {ToPrettyString(ent):console}");
}
protected override void OnEvacuationShuttle(Entity<DVCommunicationsConsoleComponent> ent, ref DVCommunicationsConsoleEvacuationShuttleMessage args)
{
base.OnEvacuationShuttle(ent, ref args);
if (!AccessReader.IsAllowed(ent, args.Actor))
return;
if (args.Call)
{
var ev = new CommunicationConsoleCallShuttleAttemptEvent(ent, default!, args.Actor);
RaiseLocalEvent(ref ev);
_roundEnd.RequestRoundEnd(args.Actor);
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Actor):player} has called the evacuation shuttle using {ToPrettyString(ent):console}");
}
else
{
_roundEnd.CancelRoundEndCountdown(args.Actor);
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Actor):player} has recalled the evacuation shuttle using {ToPrettyString(ent):console}");
}
}
protected override void OnExfiltrationShuttle(Entity<DVCommunicationsConsoleComponent> ent, ref DVCommunicationsConsoleExfiltrationShuttleMessage args)
{
base.OnExfiltrationShuttle(ent, ref args);
if (!AccessReader.IsAllowed(ent, args.Actor))
return;
if (_station.GetOwningStation(ent) is not { } station)
return;
if (args.Call)
{
_stationExfiltration.Call(station);
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Actor):player} has called the exfiltration shuttle using {ToPrettyString(ent):console}");
}
else
{
_stationExfiltration.Recall(station);
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Actor):player} has recalled the exfiltration shuttle using {ToPrettyString(ent):console}");
}
}
}
@@ -0,0 +1,88 @@
using Content.Server.AlertLevel;
using Content.Server.Audio.Jukebox;
using Content.Server.Instruments;
using Content.Server.Light.Components;
using Content.Server.Light.EntitySystems;
using Content.Server.Nuke;
using Content.Server.RoundEnd;
using Content.Shared._DV.KeycardAuthenticationDevice;
using Content.Shared.Audio.Jukebox;
using Content.Shared.Light.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.Server._DV.KeycardAuthenticationDevice;
public sealed class DVStationKeycardAuthenticationDeviceSystem : SharedDVStationKeycardAuthenticationDeviceSystem
{
[Dependency] private readonly NukeCodePaperSystem _nukeCodePaper = default!;
[Dependency] private readonly AlertLevelSystem _alertLevel = default!;
[Dependency] private readonly RoundEndSystem _roundEnd = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly PoweredLightSystem _poweredLight = default!;
[Dependency] private readonly PointLightSystem _pointLight = default!;
[Dependency] private readonly SharedUserInterfaceSystem _userInterface = default!;
[Dependency] private readonly JukeboxSystem _jukebox = default!;
protected override void Mayday(Entity<DVStationKeycardAuthenticationDeviceComponent> station)
{
base.Mayday(station);
_alertLevel.SetLevel(station, "zeta", true, true, true, true);
var alertLevel = Comp<AlertLevelComponent>(station);
var level = _prototype.Index<AlertLevelPrototype>(alertLevel.AlertLevelPrototype).Levels[alertLevel.CurrentLevel];
_roundEnd.RequestRoundEnd(level.ShuttleTime, null, null, false, cantRecall: true);
var bulbQuery = GetEntityQuery<LightBulbComponent>();
var tubeQuery = EntityQueryEnumerator<PoweredLightComponent>();
while (tubeQuery.MoveNext(out var uid, out var light))
{
if (Station.GetOwningStation(uid) != station.Owner)
continue;
if (_poweredLight.GetBulb(uid, light) is not { } bulb || !bulbQuery.TryComp(bulb, out var bulbComp))
continue;
bulbComp.LightEnergy /= 2;
bulbComp.PowerUse /= 2;
_poweredLight.SetState(uid, light.On, light);
}
var emergencyQuery = EntityQueryEnumerator<EmergencyLightComponent, PointLightComponent>();
while (emergencyQuery.MoveNext(out var uid, out var emergency, out var light))
{
if (Station.GetOwningStation(uid) != station.Owner)
continue;
_pointLight.SetEnergy(uid, emergency.MaydayEnergy, light);
_pointLight.SetRadius(uid, emergency.MaydayRadius, light);
_pointLight.SetFalloff(uid, emergency.MaydayFalloff, light);
}
var instrumentQuery = EntityQueryEnumerator<InstrumentComponent>();
while (instrumentQuery.MoveNext(out var uid, out _))
{
if (Station.GetOwningStation(uid) != station.Owner)
continue;
_userInterface.CloseUis(uid);
}
var jukeboxQuery = EntityQueryEnumerator<JukeboxComponent>();
while (jukeboxQuery.MoveNext(out var uid, out var jukebox))
{
if (Station.GetOwningStation(uid) != station.Owner)
continue;
_jukebox.Stop((uid, jukebox));
}
}
protected override void Scuttling(Entity<DVStationKeycardAuthenticationDeviceComponent> station)
{
base.Scuttling(station);
_nukeCodePaper.SendNukeCodes(station);
}
}
@@ -0,0 +1,111 @@
using Content.Server.AlertLevel;
using Content.Server.Screens.Components;
using Content.Shared._DV.Communications;
using Content.Shared._DV.Screens;
using Content.Shared.DeviceNetwork.Events;
using Content.Shared.Station;
using Robust.Shared.Timing;
namespace Content.Server._DV.Screens;
public sealed class DVScreenSystem : DVSharedScreenSystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedStationSystem _station = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVScreenComponent, DeviceNetworkPacketEvent>(OnPacket);
SubscribeLocalEvent<AlertLevelChangedEvent>(OnAlertLevelChanged);
}
private void OnPacket(Entity<DVScreenComponent> ent, ref DeviceNetworkPacketEvent args)
{
if (args.Data.TryGetValue(ShuttleTimerMasks.ShuttleMap, out _))
OnShuttlePacket(ent, ref args);
if (args.Data.TryGetValue(DVScreenPackets.Text, out (string, string)? text))
OnTextPacket(ent, text.Value, ref args);
if (args.Data.TryGetValue(DVScreenPackets.ShowBorders, out bool? showBorders))
OnBordersPacket(ent, showBorders.Value, ref args);
if (args.Data.TryGetValue(DVScreenPackets.Content, out DVScreenContent? content))
OnContentPacket(ent, content.Value, ref args);
}
private void OnShuttlePacket(Entity<DVScreenComponent> ent, ref DeviceNetworkPacketEvent args)
{
var xform = Transform(ent);
args.Data.TryGetValue(ShuttleTimerMasks.ShuttleMap, out EntityUid? shuttleMap);
args.Data.TryGetValue(ShuttleTimerMasks.SourceMap, out EntityUid? source);
args.Data.TryGetValue(ShuttleTimerMasks.DestMap, out EntityUid? dest);
args.Data.TryGetValue(ShuttleTimerMasks.Docked, out bool docked);
var screenIsAtDestination = docked;
string key;
switch (xform.MapUid)
{
// sometimes the timer transforms on FTL shuttles have a hyperspace mapuid, so matching by grid works as a fallback.
case var local when local == shuttleMap || xform.GridUid == shuttleMap:
key = ShuttleTimerMasks.ShuttleTime;
break;
case var origin when origin == source:
key = ShuttleTimerMasks.SourceTime;
break;
case var remote when remote == dest:
key = ShuttleTimerMasks.DestTime;
screenIsAtDestination = false;
break;
default:
return;
}
if (!args.Data.TryGetValue(key, out TimeSpan duration))
return;
ent.Comp.ScreenIsAtDestination = screenIsAtDestination;
ent.Comp.TargetTime = _timing.CurTime + duration;
Dirty(ent);
UpdateVisuals(ent);
}
private void OnTextPacket(Entity<DVScreenComponent> ent, (string, string) text, ref DeviceNetworkPacketEvent args)
{
ent.Comp.Line1 = text.Item1;
ent.Comp.Line2 = text.Item2;
Dirty(ent);
UpdateVisuals(ent);
}
private void OnBordersPacket(Entity<DVScreenComponent> ent, bool showBorders, ref DeviceNetworkPacketEvent args)
{
ent.Comp.ShowAlertBorder = showBorders;
Dirty(ent);
UpdateVisuals(ent);
}
private void OnContentPacket(Entity<DVScreenComponent> ent, DVScreenContent content, ref DeviceNetworkPacketEvent args)
{
ent.Comp.Content = content;
Dirty(ent);
UpdateVisuals(ent);
}
private void OnAlertLevelChanged(AlertLevelChangedEvent ev)
{
var query = EntityQueryEnumerator<DVScreenComponent>();
while (query.MoveNext(out var uid, out var screen))
{
if (_station.GetOwningStation(uid) != ev.Station)
continue;
screen.AlertLevel = ev.AlertLevel;
Dirty(uid, screen);
UpdateVisuals((uid, screen));
}
}
}
@@ -32,7 +32,6 @@ public sealed class StationExfiltrationSystem : EntitySystem
[Dependency] private readonly ShuttleSystem _shuttle = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly NavMapSystem _navMap = default!;
[Dependency] private readonly CommunicationsConsoleSystem _communicationsConsole = default!;
public override void Initialize()
{
@@ -169,7 +168,8 @@ public sealed class StationExfiltrationSystem : EntitySystem
_chat.DispatchStationAnnouncement(ent, Loc.GetString(ent.Comp.CalledAnnouncement, ("time", ent.Comp.TravelTime.TotalSeconds), ("station", Name(ent))), sender: Loc.GetString(ent.Comp.Sender), colorOverride: Color.Gold);
}
_communicationsConsole.UpdateCommsConsoleInterface();
var evt = new StationExfiltrationChangedEvent((ent, ent.Comp), true);
RaiseLocalEvent(ref evt);
}
public void Recall(Entity<StationExfiltrationComponent?> ent)
@@ -180,6 +180,10 @@ public sealed class StationExfiltrationSystem : EntitySystem
ent.Comp.ArrivalTime = null;
_chat.DispatchStationAnnouncement(ent, Loc.GetString(ent.Comp.RecalledAnnouncement, ("station", Name(ent))), sender: Loc.GetString(ent.Comp.Sender), colorOverride: Color.Gold);
_communicationsConsole.UpdateCommsConsoleInterface();
var evt = new StationExfiltrationChangedEvent((ent, ent.Comp), false);
RaiseLocalEvent(ref evt);
}
}
[ByRefEvent]
public readonly record struct StationExfiltrationChangedEvent(Entity<StationExfiltrationComponent> Station, bool Exfiltrating);
@@ -1,7 +1,7 @@
using Content.Server._DV.StationEvents.Components;
using Content.Server.Antag;
using Content.Server.Communications;
using Content.Server.StationEvents.Events;
using Content.Shared._DV.Communications;
using Content.Shared.Forensics.Components;
using Content.Shared.GameTicking.Components;
using Content.Shared.Ghost;
@@ -43,7 +43,7 @@ public sealed class FugitiveRule : StationEventSystem<FugitiveRuleComponent>
ChatSystem.DispatchGlobalAnnouncement(announcement, sender: sender, colorOverride: comp.Color);
// send the report to every comms console on the station
var query = EntityQueryEnumerator<TransformComponent, CommunicationsConsoleComponent>();
var query = EntityQueryEnumerator<TransformComponent, DVCommunicationsConsoleComponent>();
var consoles = new List<TransformComponent>();
while (query.MoveNext(out var console, out var xform, out _))
{
@@ -18,9 +18,8 @@ namespace Content.Shared.Communications
public List<string>? AlertLevels;
public string CurrentAlert;
public float CurrentAlertDelay;
public readonly TimeSpan? ExpectedExfiltrationCountdownEnd;
public CommunicationsConsoleInterfaceState(bool canAnnounce, bool canCall, List<string>? alertLevels, string currentAlert, float currentAlertDelay, TimeSpan? expectedCountdownEnd, TimeSpan? expectedExfiltrationCountdownEnd) // DeltaV - Exfiltration Shuttle
public CommunicationsConsoleInterfaceState(bool canAnnounce, bool canCall, List<string>? alertLevels, string currentAlert, float currentAlertDelay, TimeSpan? expectedCountdownEnd)
{
CanAnnounce = canAnnounce;
CanCall = canCall;
@@ -29,7 +28,6 @@ namespace Content.Shared.Communications
AlertLevels = alertLevels;
CurrentAlert = currentAlert;
CurrentAlertDelay = currentAlertDelay;
ExpectedExfiltrationCountdownEnd = expectedExfiltrationCountdownEnd; // DeltaV - Exfiltration Shuttle
}
}
@@ -90,7 +90,7 @@ public sealed partial class LabelSystem : EntitySystem
private void OnRefreshNameModifiers(Entity<LabelComponent> entity, ref RefreshNameModifiersEvent args)
{
if (!string.IsNullOrEmpty(entity.Comp.CurrentLabel))
args.AddModifier("comp-label-format", extraArgs: ("label", entity.Comp.CurrentLabel));
args.AddModifier("comp-label-format", 100, extraArgs: ("label", entity.Comp.CurrentLabel)); // Coyote: add priority of 100 to reverse order of label and baseName
}
private void OnComponentInit(Entity<PaperLabelComponent> ent, ref ComponentInit args)
@@ -300,4 +300,12 @@ public sealed partial class RevenantComponent : Component
public string HarvestingState = "harvesting";
#endregion
[DataField] public EntityUid? HauntAction; // Imp
#region Melee
/// <summary>
/// DeltaV - The amount of time a rev is revealed after making a melee attack.
/// </summary>
[DataField]
public TimeSpan MeleeRevealTime = TimeSpan.FromSeconds(2);
#endregion
}
@@ -1,9 +0,0 @@
using Robust.Shared.Serialization;
namespace Content.Shared._DV.Communications;
[Serializable, NetSerializable]
public sealed class CommunicationsConsoleExfiltrationShuttleMessage(bool call) : BoundUserInterfaceMessage
{
public readonly bool Call = call;
}
@@ -0,0 +1,136 @@
using Content.Shared._DV.KeycardAuthenticationDevice;
using Content.Shared._DV.Screens;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared._DV.Communications;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedDVCommunicationsConsoleSystem))]
public sealed partial class DVCommunicationsConsoleComponent : Component
{
[DataField]
public LocId AnnouncementTitle = "comms-console-announcement-title-station";
[DataField]
public Color AnnouncementColor = Color.Gold;
[DataField]
public SoundSpecifier AnnouncementSound = new SoundPathSpecifier("/Audio/Announcements/announce.ogg");
[DataField, AutoNetworkedField]
public bool GlobalAnnouncements;
[DataField, AutoNetworkedField]
public bool CanAnnounce = true;
[DataField, AutoNetworkedField]
public bool CanAlertLevel = true;
[DataField, AutoNetworkedField]
public bool CanCallShuttles = true;
[DataField, AutoNetworkedField]
public bool CanConfigureScreens = true;
[DataField, AutoNetworkedField]
public bool CanKeycardAuthenticationDevice = true;
[DataField, AutoNetworkedField]
public TimeSpan CanAnnounceAt = TimeSpan.Zero;
[DataField]
public TimeSpan AnnouncementInterval = TimeSpan.FromSeconds(90f);
[DataField]
public TimeSpan InitialAnnouncementDelay = TimeSpan.FromSeconds(30f);
[DataField, AutoNetworkedField]
public string CurrentAlertLevel = string.Empty;
[DataField, AutoNetworkedField]
public List<DVCommunicationsConsoleAlertLevel> AlertLevels = new();
[DataField, AutoNetworkedField]
public TimeSpan? CanSetAlertAt = TimeSpan.Zero;
[DataField, AutoNetworkedField]
public bool ShuttlesCallable = true;
[DataField, AutoNetworkedField]
public TimeSpan? ExpectedEvacuationArrival;
[DataField, AutoNetworkedField]
public TimeSpan? ExpectedEvacuationDuration;
[DataField, AutoNetworkedField]
public TimeSpan? ExpectedExfiltrationArrival;
[DataField, AutoNetworkedField]
public DVScreenContent LastConfiguredContent = DVScreenContent.Text;
[DataField, AutoNetworkedField]
public bool LastConfiguredShowBorders;
[DataField, AutoNetworkedField]
public string LastConfiguredLine1 = string.Empty;
[DataField, AutoNetworkedField]
public string LastConfiguredLine2 = string.Empty;
}
[Serializable, NetSerializable]
public readonly record struct DVCommunicationsConsoleAlertLevel(LocId AlertLevel, LocId Description, string Id, bool CanSet, Color Color);
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleEvacuationShuttleMessage(bool call) : BoundUserInterfaceMessage
{
public readonly bool Call = call;
}
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleExfiltrationShuttleMessage(bool call) : BoundUserInterfaceMessage
{
public readonly bool Call = call;
}
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleKeycardAuthenticationDeviceMessage(DVStationKeycardAction action) : BoundUserInterfaceMessage
{
public readonly DVStationKeycardAction Action = action;
}
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleAnnouncementMessage(string announcement) : BoundUserInterfaceMessage
{
public readonly string Announcement = announcement;
}
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleAlertLevelMessage(string alertLevel) : BoundUserInterfaceMessage
{
public readonly string AlertLevel = alertLevel;
}
[Serializable, NetSerializable]
public sealed class DVCommunicationsConsoleScreenConfigurationMessage(DVScreenContent content, bool showBorder, string line1, string line2) : BoundUserInterfaceMessage
{
public readonly DVScreenContent Content = content;
public readonly bool ShowBorder = showBorder;
public readonly string Line1 = line1;
public readonly string Line2 = line2;
}
[Serializable, NetSerializable]
public enum DVCommunicationsConsoleUi : byte
{
Key,
}
public static class DVScreenPackets
{
public const string Content = "dv-screen-content";
public const string ShowBorders = "dv-screen-borders";
public const string Text = "dv-screen-text";
}
@@ -0,0 +1,148 @@
using Content.Shared._DV.KeycardAuthenticationDevice;
using Content.Shared._DV.Screens;
using Content.Shared.Access.Systems;
using Content.Shared.Administration.Logs;
using Content.Shared.Chat;
using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.DeviceNetwork.Events;
using Content.Shared.DeviceNetwork.Systems;
using Content.Shared.IdentityManagement;
using Robust.Shared.Timing;
namespace Content.Shared._DV.Communications;
public abstract class SharedDVCommunicationsConsoleSystem : EntitySystem
{
[Dependency] private readonly SharedDeviceNetworkSystem _deviceNetwork = default!;
[Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] private readonly SharedChatSystem _chat = default!;
[Dependency] protected readonly AccessReaderSystem AccessReader = default!;
[Dependency] protected readonly ISharedAdminLogManager AdminLog = default!;
[Dependency] private readonly SharedDVStationKeycardAuthenticationDeviceSystem _stationKeycardAuthenticationDevice = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DVCommunicationsConsoleComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<DVCommunicationsConsoleComponent, DeviceNetworkPacketEvent>(OnPacketReceive);
Subs.BuiEvents<DVCommunicationsConsoleComponent>(DVCommunicationsConsoleUi.Key,
subs =>
{
subs.Event<DVCommunicationsConsoleEvacuationShuttleMessage>(OnEvacuationShuttle);
subs.Event<DVCommunicationsConsoleExfiltrationShuttleMessage>(OnExfiltrationShuttle);
subs.Event<DVCommunicationsConsoleScreenConfigurationMessage>(OnConfiguration);
subs.Event<DVCommunicationsConsoleAnnouncementMessage>(OnAnnouncement);
subs.Event<DVCommunicationsConsoleAlertLevelMessage>(OnAlertLevel);
subs.Event<DVCommunicationsConsoleKeycardAuthenticationDeviceMessage>(OnKeycardAuthenticationDevice);
});
}
private void OnPacketReceive(Entity<DVCommunicationsConsoleComponent> ent, ref DeviceNetworkPacketEvent args)
{
if (args.Data.TryGetValue(DVScreenPackets.Text, out (string, string)? text))
{
ent.Comp.LastConfiguredLine1 = text.Value.Item1;
ent.Comp.LastConfiguredLine2 = text.Value.Item2;
Dirty(ent);
}
if (args.Data.TryGetValue(DVScreenPackets.ShowBorders, out bool? showBorders))
{
ent.Comp.LastConfiguredShowBorders = showBorders.Value;
Dirty(ent);
}
if (args.Data.TryGetValue(DVScreenPackets.Content, out DVScreenContent? content))
{
ent.Comp.LastConfiguredContent = content.Value;
Dirty(ent);
}
}
protected virtual void OnMapInit(Entity<DVCommunicationsConsoleComponent> ent, ref MapInitEvent args)
{
ent.Comp.CanAnnounceAt = Timing.CurTime + ent.Comp.InitialAnnouncementDelay;
Dirty(ent);
}
private void OnAnnouncement(Entity<DVCommunicationsConsoleComponent> ent, ref DVCommunicationsConsoleAnnouncementMessage args)
{
if (!ent.Comp.CanAnnounce)
return;
if (Timing.CurTime <= ent.Comp.CanAnnounceAt)
return;
if (!AccessReader.IsAllowed(args.Actor, ent))
return;
var identity = new TryGetIdentityShortInfoEvent(ent, args.Actor);
RaiseLocalEvent(identity);
Loc.TryGetString(ent.Comp.AnnouncementTitle, out var title);
title ??= ent.Comp.AnnouncementTitle;
var msg = args.Announcement;
msg += "\n" + Loc.GetString("comms-console-announcement-sent-by") + " " + identity.Title;
if (ent.Comp.GlobalAnnouncements)
{
_chat.DispatchGlobalAnnouncement(msg, title, announcementSound: ent.Comp.AnnouncementSound, colorOverride: ent.Comp.AnnouncementColor);
AdminLog.Add(LogType.Chat, LogImpact.Low, $"{ToPrettyString(args.Actor):player} sent the following global announcement using {ToPrettyString(ent):console}: {msg:message}");
}
else
{
_chat.DispatchStationAnnouncement(ent, msg, title, announcementSound: ent.Comp.AnnouncementSound, colorOverride: ent.Comp.AnnouncementColor);
AdminLog.Add(LogType.Chat, LogImpact.Low, $"{ToPrettyString(args.Actor):player} sent the following station announcement using {ToPrettyString(ent):console}: {msg:message}");
}
ent.Comp.CanAnnounceAt = Timing.CurTime + ent.Comp.AnnouncementInterval;
Dirty(ent);
}
private void OnConfiguration(Entity<DVCommunicationsConsoleComponent> ent, ref DVCommunicationsConsoleScreenConfigurationMessage args)
{
if (!ent.Comp.CanConfigureScreens)
return;
if (!AccessReader.IsAllowed(args.Actor, ent))
return;
ent.Comp.LastConfiguredLine1 = args.Line1;
ent.Comp.LastConfiguredLine2 = args.Line2;
ent.Comp.LastConfiguredShowBorders = args.ShowBorder;
ent.Comp.LastConfiguredContent = args.Content;
Dirty(ent);
var payload = new NetworkPayload
{
[DVScreenPackets.Content] = args.Content,
[DVScreenPackets.ShowBorders] = args.ShowBorder,
[DVScreenPackets.Text] = (args.Line1, args.Line2),
};
AdminLog.Add(LogType.Chat, LogImpact.Low, $"{ToPrettyString(args.Actor):player} configured the following text using {ToPrettyString(ent):console}: {args.Line1:line1} {args.Line2:line2}");
_deviceNetwork.QueuePacket(ent, null, payload);
}
protected virtual void OnExfiltrationShuttle(Entity<DVCommunicationsConsoleComponent> ent,
ref DVCommunicationsConsoleExfiltrationShuttleMessage args)
{
}
protected virtual void OnEvacuationShuttle(Entity<DVCommunicationsConsoleComponent> ent,
ref DVCommunicationsConsoleEvacuationShuttleMessage args)
{
}
protected virtual void OnAlertLevel(Entity<DVCommunicationsConsoleComponent> ent,
ref DVCommunicationsConsoleAlertLevelMessage args)
{
}
private void OnKeycardAuthenticationDevice(Entity<DVCommunicationsConsoleComponent> ent,
ref DVCommunicationsConsoleKeycardAuthenticationDeviceMessage args)
{
_stationKeycardAuthenticationDevice.TrySwipe(args.Actor, ent, args.Action);
}
}
@@ -0,0 +1,7 @@
using Robust.Shared.GameStates;
namespace Content.Shared._DV.KeycardAuthenticationDevice;
[RegisterComponent, NetworkedComponent]
[Access(typeof(SharedDVStationKeycardAuthenticationDeviceSystem))]
public sealed partial class DVStationKeycardAuthenticationDeviceAlreadySwipedComponent : Component;
@@ -0,0 +1,50 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared._DV.KeycardAuthenticationDevice;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause]
[Access(typeof(SharedDVStationKeycardAuthenticationDeviceSystem))]
public sealed partial class DVStationKeycardAuthenticationDeviceComponent : Component
{
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField, AutoPausedField]
public TimeSpan AccessibleAfter = TimeSpan.Zero;
[DataField]
public TimeSpan FailureDelay = TimeSpan.FromMinutes(2);
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField, AutoPausedField]
public TimeSpan? SwipesStartedAt = null;
[DataField]
public TimeSpan SwipeWindow = TimeSpan.FromSeconds(20);
[DataField(required: true)]
public Dictionary<DVStationKeycardAction, int> ActionThresholds;
[DataField, AutoNetworkedField]
public int Swipes;
[DataField, AutoNetworkedField]
public DVStationKeycardAction? SwipingFor;
[DataField]
public LocId FailureAnnouncementSender = "keycard-authentication-device-sender";
[DataField]
public LocId FailureAnnouncement = "keycard-authentication-device-warning";
[DataField]
public Color FailureAnnouncementColor = Color.FromHex("#e93a9a");
[DataField]
public TimeSpan FailureElectrocutionDuration = TimeSpan.FromSeconds(5);
}
[Serializable, NetSerializable]
public enum DVStationKeycardAction
{
Mayday,
Scuttling,
}
@@ -0,0 +1,124 @@
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Chat;
using Content.Shared.Electrocution;
using Content.Shared.Station;
using Robust.Shared.Audio;
using Robust.Shared.Timing;
namespace Content.Shared._DV.KeycardAuthenticationDevice;
public abstract class SharedDVStationKeycardAuthenticationDeviceSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] protected readonly SharedStationSystem Station = default!;
[Dependency] private readonly SharedElectrocutionSystem _electrocution = default!;
[Dependency] private readonly SharedChatSystem _chat = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<DVStationKeycardAuthenticationDeviceComponent>();
while (query.MoveNext(out var uid, out var keycard))
{
if (keycard.SwipesStartedAt is not { } startedAt || _timing.CurTime <= startedAt + keycard.SwipeWindow)
continue;
StopSwipes((uid, keycard), true);
}
}
private void StopSwipes(Entity<DVStationKeycardAuthenticationDeviceComponent> station, bool failed)
{
station.Comp.SwipesStartedAt = null;
station.Comp.Swipes = 0;
station.Comp.SwipingFor = null;
if (failed)
{
station.Comp.AccessibleAfter = _timing.CurTime + station.Comp.FailureDelay;
_chat.DispatchStationAnnouncement(station,
Loc.GetString(station.Comp.FailureAnnouncement),
Loc.GetString(station.Comp.FailureAnnouncementSender),
announcementSound: new SoundPathSpecifier("/Audio/_DV/Announcements/attention.ogg"),
colorOverride: station.Comp.FailureAnnouncementColor);
}
Dirty(station);
var query = EntityQueryEnumerator<DVStationKeycardAuthenticationDeviceAlreadySwipedComponent>();
while (query.MoveNext(out var uid, out _))
{
if (failed)
{
_electrocution.TryDoElectrocution(uid,
null,
10,
station.Comp.FailureElectrocutionDuration,
true,
ignoreInsulation: true);
}
RemCompDeferred<DVStationKeycardAuthenticationDeviceAlreadySwipedComponent>(uid);
}
}
private void Swipe(Entity<DVStationKeycardAuthenticationDeviceComponent> station, EntityUid user, DVStationKeycardAction action)
{
if (!station.Comp.ActionThresholds.TryGetValue(action, out var threshold))
return;
station.Comp.SwipesStartedAt ??= _timing.CurTime;
station.Comp.SwipingFor = action;
station.Comp.Swipes++;
AddComp<DVStationKeycardAuthenticationDeviceAlreadySwipedComponent>(user);
Dirty(station);
if (station.Comp.Swipes >= threshold)
{
StopSwipes(station, false);
DoAction(station, action);
}
}
private void DoAction(Entity<DVStationKeycardAuthenticationDeviceComponent> station, DVStationKeycardAction action)
{
switch (action)
{
case DVStationKeycardAction.Mayday:
Mayday(station);
break;
case DVStationKeycardAction.Scuttling:
Scuttling(station);
break;
}
}
protected virtual void Mayday(Entity<DVStationKeycardAuthenticationDeviceComponent> station)
{
}
protected virtual void Scuttling(Entity<DVStationKeycardAuthenticationDeviceComponent> station)
{
}
public void TrySwipe(EntityUid user, EntityUid console, DVStationKeycardAction action)
{
if (HasComp<DVStationKeycardAuthenticationDeviceAlreadySwipedComponent>(console))
return;
if (Station.GetOwningStation(user) is not { } station || !TryComp<DVStationKeycardAuthenticationDeviceComponent>(station, out var keycard))
return;
if (TryComp<AccessReaderComponent>(console, out var accessReader) && !_accessReader.IsAllowed(user, console, accessReader))
return;
if (keycard.SwipingFor is { } swipingFor && swipingFor != action)
return;
if (_timing.CurTime <= keycard.AccessibleAfter)
return;
Swipe((station, keycard), user, action);
}
}
@@ -0,0 +1,55 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared._DV.Screens;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true), AutoGenerateComponentPause]
[Access(typeof(DVSharedScreenSystem))]
public sealed partial class DVScreenComponent : Component
{
[DataField, AutoNetworkedField]
public string? AlertLevel; // I don't like this but uhhh the prototype isn't client-accessible
[DataField, AutoNetworkedField]
public bool ShowAlertBorder;
[DataField, AutoNetworkedField]
public DVScreenContent Content = DVScreenContent.Text;
#region Text Screens
[DataField, AutoNetworkedField]
public string Line1 = string.Empty;
[DataField, AutoNetworkedField]
public string Line2 = string.Empty;
#endregion
#region ETA Screens
[DataField, AutoNetworkedField]
public bool ScreenIsAtDestination;
[DataField, AutoNetworkedField, AutoPausedField]
public TimeSpan TargetTime = TimeSpan.Zero;
#endregion
}
[Serializable, NetSerializable]
public enum DVScreenVisuals : byte
{
AlertLevel,
ShowAlertBorder,
Content,
}
[Serializable, NetSerializable]
public enum DVScreenContent : byte
{
Text,
CurrentTime,
EstimatedTimeOfArrival,
AlertLevel,
}
@@ -0,0 +1,13 @@
namespace Content.Shared._DV.Screens;
public abstract class DVSharedScreenSystem : EntitySystem
{
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
protected void UpdateVisuals(Entity<DVScreenComponent> ent)
{
_appearance.SetData(ent.Owner, DVScreenVisuals.AlertLevel, ent.Comp.AlertLevel ?? string.Empty);
_appearance.SetData(ent.Owner, DVScreenVisuals.ShowAlertBorder, ent.Comp.ShowAlertBorder);
_appearance.SetData(ent.Owner, DVScreenVisuals.Content, ent.Comp.Content);
}
}
@@ -0,0 +1,10 @@
using Robust.Shared.Serialization;
namespace Content.Shared._DV.Screens;
[Serializable, NetSerializable]
public enum DVTextScreenVisualLayers : byte
{
Line1,
Line2,
}
@@ -0,0 +1,10 @@
using Robust.Shared.Configuration;
using Content.Shared.CCVar.CVarAccess;
using Content.Shared.Administration;
namespace Content.Shared.Starlight.CCVar;
[CVarDefs]
public sealed partial class StarlightCCVars
{
}
@@ -0,0 +1,13 @@
using Robust.Shared.Configuration;
namespace Content.Shared.Starlight.CCVar;
public sealed partial class StarlightCCVars
{
/// <summary>
/// A newline-separated list of saved labels for the hand labeler tool
/// </summary>
public static readonly CVarDef<string> HandLabelerSavedLabels =
CVarDef.Create("interface.hand_labeler_saved_labels", "", CVar.CLIENTONLY | CVar.ARCHIVE);
}
Binary file not shown.
+9
View File
@@ -371,5 +371,14 @@ Entries:
id: 41
time: '2026-08-22T16:18:32.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6435
- author: einknusprigestoast
changes:
- message: ERT elite hardsuits now have different values
type: Tweak
- message: added new guns to ERT gamma and amber loadouts
type: Add
id: 42
time: '2026-09-09T14:07:35.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6239
Name: DeltaVAdmin
Order: 5
+277 -249
View File
@@ -1,253 +1,4 @@
Entries:
- author: zelezniciar
changes:
- message: Added a generic Slavic accent that can be selected as a character trait.
Very Nice!
type: Add
id: 2136
time: '2026-02-27T18:30:56.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5264
- author: kotobdev
changes:
- message: You can now always equip items to your suit storage, even without any
outer clothing!
type: Add
id: 2137
time: '2026-02-27T18:55:24.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5300
- author: verybigman311
changes:
- message: The Crusher can now Wideswing with right click.
type: Tweak
id: 2138
time: '2026-02-28T08:50:25.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5327
- author: AeraAuling
changes:
- message: Removed PKA upgrade kits for Fire-Rate and Indoors.
type: Remove
- message: PKA damage stats have been tweaked.
type: Tweak
id: 2139
time: '2026-02-28T10:26:37.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5311
- author: makyo
changes:
- message: Some clothing/item/etc forced accents removed; they can still be added
in traits!
type: Tweak
id: 2140
time: '2026-02-28T12:31:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5343
- author: Cepelinas1
changes:
- message: NanoTrasen has permitted Engineering to choose between a voidsuit and
a hardsuit for their work. Check your lockers!
type: Add
- message: Increased Engineering Voidsuit speed by 5%.
type: Tweak
id: 2141
time: '2026-02-28T14:23:13.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5317
- author: Darklyac
changes:
- message: Added 9 new Lobby Music and 11 new Jukebox Music!
type: Add
id: 2142
time: '2026-02-28T18:13:51.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5424
- author: Pharaz4
changes:
- message: Added cloth wraps!
type: Add
id: 2143
time: '2026-02-28T20:06:08.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5335
- author: Stxcking
changes:
- message: Fixed medborg crew monitor not getting power and being able to remove
power cell.
type: Fix
id: 2144
time: '2026-02-28T20:42:44.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5342
- author: Pharaz4
changes:
- message: Fixed blukie and paramed suit not displaying for harpy.
type: Fix
id: 2145
time: '2026-03-01T11:18:43.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5414
- author: Velcroboy
changes:
- message: Wizard now starts in the Wizard's Den and gets a teleport scroll
type: Tweak
id: 2146
time: '2026-03-01T13:38:18.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5215
- author: rebe83
changes:
- message: Bottles, vials, and chem injectors no longer fit inside cigarette boxes.
Use a combat kit like the rest of us!
type: Tweak
id: 2147
time: '2026-03-01T14:12:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5402
- author: Stxcking
changes:
- message: Health analyzer can show who claimed a patient.
type: Tweak
id: 2148
time: '2026-03-01T19:47:57.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5110
- author: pootslap
changes:
- message: Rat servants are slightly faster but weaker.
type: Tweak
- message: Rat Kings have a few new titles and are now more clearly labelled as
antagonists.
type: Tweak
id: 2149
time: '2026-03-02T17:48:25.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5326
- author: JoulesBerg
changes:
- message: Vents, air injectors, and pumps can be pipes in their alternate configurations
now.
type: Add
id: 2150
time: '2026-03-02T18:17:30.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5372
- author: Halo3moth
changes:
- message: Hos has a new robe for a significant aura increase, amazing sprites by
Ci1rus
type: Add
id: 2151
time: '2026-03-02T19:36:29.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5425
- author: Jimboe
changes:
- message: SUBMARINE HAS GOTTEN SUBBIER - Power rework completed, Minor Atmos changes
to engineering. Atmos will eventually all reflect engineering soon. Solars have
been improved!
type: Tweak
id: 2152
time: '2026-03-03T03:16:06.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5394
- author: Velcroboy
changes:
- message: 'Evac Shuttles: NTES- Fishbowl and NTES-BC20 are APC compliant'
type: Tweak
id: 2153
time: '2026-03-03T04:32:39.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5457
- author: SirRequiem
changes:
- message: 'Terra: Added additional meteor shielding, meteor avoidance zones, Robotics
console, AI Recovery Console, AI subnet/cameras, mail cart, and medical crash
cart'
type: Add
- message: 'Terra: Waste and Distro have pre-enabled pumps now, and power bank has
been slightly improved'
type: Tweak
- message: 'Terra: APCs are now all below 20kw in regards to the new breaker system'
type: Fix
id: 2154
time: '2026-03-04T01:23:21.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5432
- author: Woljif
changes:
- message: Sec jetpacks are no longer mini-jetpacks and can hold 3.0L
type: Tweak
id: 2155
time: '2026-03-05T20:46:13.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5357
- author: EmberAstra
changes:
- message: Fixed the Research Digi-Board storage space lacking an UI. Did you even
know it had some?
type: Fix
id: 2156
time: '2026-03-05T21:17:37.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5434
- author: Stxcking
changes:
- message: Changed the mailbox sprite!
type: Tweak
id: 2157
time: '2026-03-05T21:18:52.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5433
- author: EmberAstra
changes:
- message: Added the power digi-board! Monitor your energy situation on the move!
Find it in CE's locker.
type: Add
id: 2158
time: '2026-03-06T15:36:34.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5435
- author: BarryNorfolk
changes:
- message: Silicons no longer change their battery usage depending on the temperature
around them
type: Remove
- message: IPCs now once again have working alerts for their batteries
type: Fix
id: 2159
time: '2026-03-06T16:10:00.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5345
- author: marigauge
changes:
- message: reverted soretizone changes hopefully fixing flashing
type: Fix
id: 2160
time: '2026-03-07T09:45:22.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5391
- author: Pharaz4
changes:
- message: Added kitchen freezer.
type: Add
id: 2161
time: '2026-03-07T16:24:25.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5443
- author: Cepelinas1
changes:
- message: 'A new antag role has been added: Internal Affairs! NanoTrasen is hiring
any employees who would love to protect the company.'
type: Add
id: 2162
time: '2026-03-07T20:35:19.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5450
- author: Coryler
changes:
- message: Add Universal Pinpointer to the Syndicate Uplink
type: Add
id: 2163
time: '2026-03-09T09:12:29.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5471
- author: HameyTychol
changes:
- message: Made more items recyclable
type: Tweak
id: 2164
time: '2026-03-09T09:43:25.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5398
- author: snowywinters
changes:
- message: Watchdogs now work as a death rattle also decreased the price to 9k
type: Tweak
- message: Fixed watchdogs not working
type: Fix
id: 2165
time: '2026-03-09T10:17:49.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5475
- author: Woljif
changes:
- message: The Kammerer is now a 2x4 in your bag
type: Tweak
id: 2166
time: '2026-03-09T10:55:09.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5469
- author: DisposableCrewmember42
changes:
- message: Conspirators now requires 32 connected players to roll. The ingame delay
@@ -4420,4 +4171,281 @@
id: 2636
time: '2026-08-23T12:57:01.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6439
- author: ShepardToTheStars
changes:
- message: Mothroach grenades actually work again.
type: Fix
id: 2637
time: '2026-08-23T15:00:35.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6447
- author: ShepardToTheStars
changes:
- message: Chameleon thieving gloves have been removed from the syndicate uplink.
You can always ask nicely, right?
type: Remove
id: 2638
time: '2026-08-24T15:13:51.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6425
- author: ShepardToTheStars
changes:
- message: The health analyzer will again show if the patient is unborgable, unrevivable,
or uncloneable.
type: Fix
id: 2639
time: '2026-08-24T16:23:07.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6446
- author: ShepardToTheStars
changes:
- message: Ninja's katana dash now has a 5 second cooldown between uses.
type: Tweak
- message: Ninja's katana dash now takes 30 seconds to recharge each use, up from
20 seconds.
type: Tweak
- message: Reduced skia's healing in the dark from 5 of each damage type to 2 of
each damage type.
type: Tweak
- message: Increased skia's damage from light from 1.5 brute to 2 brute.
type: Tweak
- message: Revenant's melee attack will now reveal them for 2 seconds.
type: Tweak
id: 2640
time: '2026-08-26T08:34:48.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6410
- author: SumofThreeParts
changes:
- message: The Patos can now be purchased from logistics.
type: Add
id: 2641
time: '2026-08-27T14:29:39.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6361
- author: ShepardToTheStars
changes:
- message: Diona who become trees are 'rooted' in place again.
type: Fix
id: 2642
time: '2026-08-27T18:31:59.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6456
- author: sowelipililimute, ShepardToTheStars
changes:
- message: Communications consoles have been redesigned!
type: Add
- message: Command can now declare alert level Zeta as a form of mayday to call
an expedited evacuation. Two authorizations are required.
type: Add
- message: Command can now request the nuclear authentication codes to scuttle the
station. Three authorizations are required.
type: Add
- message: Status displays have been redesigned and can now be configured to show
scrolling text, an image for the alert level, borders for the alert level, the
current time, or shuttle ETA/ETD
type: Add
- message: Code Orange has been removed because Zeta now exists.
type: Remove
id: 2643
time: '2026-08-27T18:37:40.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5954
- author: SumofThreeParts
changes:
- message: the hushpup now makes less sound when fired.
type: Tweak
id: 2644
time: '2026-08-27T19:24:13.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6438
- author: Coryler
changes:
- message: You can now save labels between rounds.
type: Add
- message: The original item name and label are now swapped.
type: Tweak
id: 2645
time: '2026-08-27T19:26:08.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6432
- author: CarolCuchara
changes:
- message: New caseless shotgun shells that wont leave behind a trace!
type: Add
- message: The Hushpup now comes equiped with caseless shotgun shells!
type: Tweak
id: 2646
time: '2026-08-28T16:38:08.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6457
- author: Vapetastic-Gaming
changes:
- message: Survival Scheduler has been slightly tamed, and will give moments of
calm, while also applying pressure via spawns. Survival Scheduler refused to
read you a bedtime story, sorry chat.
type: Tweak
id: 2647
time: '2026-08-28T23:54:33.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6440
- author: BriBrooo
changes:
- message: Hydroponics' booklet on reagents contained an error.
type: Fix
id: 2648
time: '2026-09-06T23:35:52.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6483
- author: nlaky
changes:
- message: Vulp alt tail can now wag
type: Tweak
id: 2649
time: '2026-09-07T00:17:23.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6480
- author: Macrocosm, Stxcking
changes:
- message: Added 20+ new Thaven markings, most notably, tails!
type: Add
- message: Thavens can select their undergarments again.
type: Fix
- message: Thaven markings display the correct locale marking name.
type: Fix
- message: Thavens have unique organ sprites now.
type: Tweak
id: 2650
time: '2026-09-07T00:18:45.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6162
- author: AnimatorBrie
changes:
- message: Added surplus boots, a strictly-cosmetic variant of jackboots. Available
now at your local Clothesmate vendor.
type: Add
id: 2651
time: '2026-09-07T00:33:43.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6472
- author: StarboundSolaris
changes:
- message: Added even more names for Pitbulls and Ventbulls!
type: Add
- message: Ventbulls also now actually roam the vents. Godspeed mice mains.
type: Add
- message: Ventbulls now appear as ghost roles!
type: Add
id: 2652
time: '2026-09-09T14:15:30.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6449
- author: pixelStrife
changes:
- message: Ethanol content of drinks has been re-standardized. No more adding ethanol
directly, only metabolizing. (Non-ethanol substances too!)
type: Fix
- message: Silencer is once again non-alcoholic, for mimes that would rather keep
their wits about them.
type: Fix
id: 2653
time: '2026-09-09T14:18:38.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6486
- author: EmberAstra
changes:
- message: Shadekins can now have hair and facial hair.
type: Add
id: 2654
time: '2026-09-09T14:54:45.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6453
- author: SumofThreeParts
changes:
- message: Added the Anaconda to the uplink.
type: Add
id: 2655
time: '2026-09-09T15:49:18.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6458
- author: BarryNorfolk
changes:
- message: Fixed displays for ETA/ETD not displaying
type: Fix
id: 2656
time: '2026-09-10T23:39:44.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6497
- author: kotobdev
changes:
- message: Asakim should, once again, be very rare.
type: Fix
id: 2657
time: '2026-09-13T22:19:40.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6455
- author: Pinoinha
changes:
- message: Fixed service borgs being unable to pickup beer bottles when using the
fishing module
type: Fix
id: 2658
time: '2026-09-14T17:44:42.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6503
- author: SumofThreeParts
changes:
- message: Glimmer prober locks out at 600 glimmer instead of 750 glimmer.
type: Tweak
id: 2659
time: '2026-09-16T12:31:05.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6493
- author: Apersos-coll
changes:
- message: Added new crewsided heavy laser gun the Unstable Core Refractor, for
when stable reactors weren't enough.
type: Add
id: 2660
time: '2026-09-16T12:44:37.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6491
- author: pixelStrife
changes:
- message: Ovinia now make actual noise when gasping and deathgasping (instead of
text only.)
type: Tweak
id: 2661
time: '2026-09-17T04:05:19.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6481
- author: keekee38
changes:
- message: slimes can have prosthetic limbs too
type: Add
id: 2662
time: '2026-09-17T04:19:40.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6496
- author: kotobdev
changes:
- message: Removed a shitmed-remnant Asakim objective.
type: Remove
- message: Asakim ghostrole rules have been reworded to be a little less friendly.
type: Tweak
- message: Asakim armor now slows any non-Asakim by 80%, to discourage crewmembers
from intentionally springlocking themselves.
type: Tweak
- message: Asakim shouldn't get stuck in doors.
type: Fix
id: 2663
time: '2026-09-17T04:22:46.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6452
- author: Apersos-coll
changes:
- message: Somebody at CC had an idea and too much money to spend, and somehow got
a new pulse style pistol designed. The EPU-U001
type: Add
id: 2664
time: '2026-09-17T10:41:02.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6507
- author: Apersos-coll
changes:
- message: Fixed Unstable Core Refractors back/suit storage sprites
type: Fix
id: 2665
time: '2026-09-17T14:03:34.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6517
- author: stormyatt
changes:
- message: hitmen now get freelancer comms roundstart
type: Add
- message: thieves now get freelancer comms roundstart
type: Add
- message: traitors can now buy freelancer comms for 1tc. hiring hours
type: Add
id: 2666
time: '2026-09-17T14:04:53.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6495
- author: keekee38
changes:
- message: med kits no longer fit into pockets
type: Fix
id: 2667
time: '2026-09-20T20:10:57.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6523
Order: 1
+14
View File
@@ -1087,4 +1087,18 @@
id: 125
time: '2026-07-14T00:30:06.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6242
- author: Field Command
changes:
- message: 'Central Command: New CC is here!'
type: Add
id: 126
time: '2026-09-05T14:03:09.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6198
- author: BriBrooo
changes:
- message: Added a light gray version of the air sensor.
type: Add
id: 127
time: '2026-09-17T03:01:35.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6340
Order: 3
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,5 +1,60 @@
comms-console-announcement-title-unauthorized = Unauthorized
comms-console-menu-call-exfiltration = Call exfiltration shuttle
comms-console-menu-exfiltration-shuttle-button-tooltip = Calls or recalls the exfiltration shuttle.
comms-console-menu-exfiltration-time-remaining = ETA of exfiltration shuttle: {$time}
comms-console-menu-recall-exfiltration = Recall exfiltration shuttle
comms-console-menu-screen-content =
.Text = Text
.CurrentTime = Current Time
.EstimatedTimeOfArrival = ETA / ETD
.AlertLevel = Alert Level
comms-console-menu-tab =
.Announcement = Make an announcement
.Screen = Configure status displays
.Shuttles = Manage shuttles
.AlertLevel = Set the alert level
.KeycardAuthenticationDevice = Keycard Authentication Device
comms-console-menu-line-1 = Line 1:
comms-console-menu-line-2 = Line 2:
comms-console-menu-alert-level-border = Alert level border:
comms-console-menu-alert-level = Alert level
comms-console-menu-screen-contents = Screen contents:
comms-console-menu-send-announcement = Send announcement
comms-console-menu-update-screen-text = Update text
comms-console-menu-enable-border = Enable alert level border
comms-console-menu-home = Home
comms-console-menu-emergency-shuttle = Emergency shuttle
comms-console-menu-exfiltration-shuttle = Exfiltration shuttle
comms-console-menu-shuttle-not-coming = This shuttle is not currently requested.
comms-console-menu-shuttle-eta = This shuttle will arrive in {$time}.
comms-console-menu-screen-text = Screen text
comms-console-menu-screen-configuration = Screen options
comms-console-menu-current-alert-level = The current alert level is [color={$color}]{$name}[/color]. {$description}
comms-console-menu-change-alert-level = Change alert level
comms-console-menu-station-title = Station
comms-console-menu-transit-title = Transit
comms-console-menu-emergency-title = Emergency
comms-console-menu-declare-mayday =
.title = Declare mayday
.desc = Declare the station unfit for life and send out a distress signal to all nearby vessels. Requires two simultaneous authorizations.
.button = Declare Code Zeta
comms-console-menu-request-codes =
.title = Scuttle the station
.desc = Order the destruction of the station to prevent capture, containment breach, or further threats to the sector. Requires three simultaneous authorizations.
.button = Request nuclear authorization codes
comms-console-menu-call-emergency =
.True = Call emergency shuttle
.False = Recall emergency shuttle
comms-console-menu-call-exfiltration =
.True = Call exfiltration shuttle
.False = Recall exfiltration shuttle
comms-console-menu-announcement-text = Announcement text
@@ -13,13 +13,13 @@ names-pitbull-dataset-11 = Echo
names-pitbull-dataset-12 = Cuddles
names-pitbull-dataset-13 = Killer
names-pitbull-dataset-14 = Paisley
names-pitbull-dataset-15 = Echo
names-pitbull-dataset-15 = Ravager
names-pitbull-dataset-16 = Sweetie
names-pitbull-dataset-17 = Tutu
names-pitbull-dataset-18 = Reaper
names-pitbull-dataset-19 = Peaches
names-pitbull-dataset-20 = Cujo
names-pitbull-dataset-21 = Cuddles
names-pitbull-dataset-21 = Chompers
names-pitbull-dataset-22 = Lucifer
names-pitbull-dataset-23 = Daisy
names-pitbull-dataset-24 = Blaze
@@ -64,3 +64,41 @@ names-pitbull-dataset-60 = Menace
names-pitbull-dataset-61 = Buddy
names-pitbull-dataset-62 = Rocky
names-pitbull-dataset-63 = Boulder
names-pitbull-dataset-64 = Hellspawn
names-pitbull-dataset-65 = Bape
names-pitbull-dataset-66 = Skullbreaker
names-pitbull-dataset-67 = Billy
names-pitbull-dataset-68 = Bobby
names-pitbull-dataset-69 = Steve
names-pitbull-dataset-70 = Phil
names-pitbull-dataset-71 = Tesla
names-pitbull-dataset-72 = Creature
names-pitbull-dataset-73 = Flowery
names-pitbull-dataset-74 = Jarona
names-pitbull-dataset-75 = Raider
names-pitbull-dataset-76 = Shitlet
names-pitbull-dataset-77 = Mr Worldwide
names-pitbull-dataset-78 = Rat
names-pitbull-dataset-79 = Cynophobia
names-pitbull-dataset-80 = Divine Comedy
names-pitbull-dataset-81 = Comedy
names-pitbull-dataset-82 = Irenic
names-pitbull-dataset-83 = Fluffy
names-pitbull-dataset-84 = Chaser
names-pitbull-dataset-85 = Pitt
names-pitbull-dataset-86 = Bull
names-pitbull-dataset-87 = Sakura
names-pitbull-dataset-88 = Singularity
names-pitbull-dataset-89 = Singuloose
names-pitbull-dataset-90 = Mustard
names-pitbull-dataset-91 = Gravy
names-pitbull-dataset-92 = Tesloose
names-pitbull-dataset-93 = Root Beer
names-pitbull-dataset-94 = Tritfire
names-pitbull-dataset-95 = Spoonlicker
names-pitbull-dataset-96 = Devil
names-pitbull-dataset-97 = Shepard
names-pitbull-dataset-98 = Gaster
names-pitbull-dataset-99 = Roots
names-pitbull-dataset-100 = Friend
names-pitbull-dataset-101 = Pookie
@@ -1,9 +1,9 @@
ghost-role-information-asakim-name = Asakim Warrior
ghost-role-information-asakim-description = A genetically enhanced bioweapon, stranded in the sector after cryostasis failure.
ghost-role-information-asakim-rules =
You are a [color=yellow][bold]Free-Agent[/bold][/color]. You may pursue your given objectives, or find your own way through life.
You are a [color=yellow][bold]Free-Agent[/bold][/color]. Your objectives will put you in varying levels of conflict with the station.
You have [color=red]no knowledge[/color] (maybe basic at most) [color=red]of this sector of space, its inhabitants, its factions, or its culture[/color]. While you cannot speak their language, you can understand it.
You may kill your targets if you have any, and you may kill to defend yourself and your property. [color=green]Civilians and the innocent are not your enemy[/color], and may be useful to you (if you can get past the language barrier - try an AAC tablet!). Fight with honor.
You may kill your targets if you have any, and you may kill to defend yourself and your property. [color=yellow]You should be somewhat wary of crewmembers, especially Security[/color]- but they may be useful to you (if you can get past the language barrier - try an AAC tablet!). Fight with honor.
asakim-role-briefing =
You are an Asakim, a genetically-engineered weapon from a distant part of space.
You've awoken from long-term cryosleep in an unfamiliar sector, and an unfamiliar time.
@@ -37,6 +37,8 @@ construction-graph-tag-ancientbook = Damaged Ancient Book
# Weapons
construction-graph-tag-silversword = silver sword
construction-graph-tag-unstable-reactor-core = Unstable Reactor Core
construction-graph-tag-unstable-reactor-housing = Unstable Reactor Housing
# Other
construction-graph-tag-jug = jug
@@ -0,0 +1,2 @@
keycard-authentication-device-sender = Keycard Authentication Device
keycard-authentication-device-warning = Unsuccessful authorization attempt of the keycard authentication device detected. Administering deterrence measures and initiating keycard authentication device lockdown.
@@ -0,0 +1,3 @@
status-display-eta = -ETA-
status-display-etd = -ETD-
status-display-time = TIME
@@ -20,3 +20,6 @@ uplink-dualswords-desc = A set of dual swords made for those who prefer somethin
uplink-leveraction-name = SKL93 AP Bundle
uplink-leveraction-desc = A bundle containing a SKL93 lever action sniper loaded with AP ammo. Comes with a spare box of standard magnum.
uplink-anaconda-name = Anaconda Bundle
uplink-anaconda-desc = A inaccurate one handed SMG with a 100 bullet mag. Perfect for laying down supressive fire.
@@ -7,6 +7,9 @@ ert-amber-gun-desc-aegun = One advanced energy gun, for both lethal and non-leth
ert-amber-gun-name-mixlaser = Mixed Laser bundle
ert-amber-gun-desc-mixlaser = A disabler SMG together with a Laser Carbine, bundled with a portable recharger.
ert-amber-gun-name-kammerer = Kammerer
ert-amber-gun-desc-kammerer = Do not be afraid Captain.
ert-medkit-name = First aid kit
ert-medkit-desc = A simple first aid kit, dont get shoot too hard.
@@ -76,6 +79,9 @@ ert-Immolatorkit-desc = The original firestarter bundled together with a portabl
ert-IK60kit-name = IK-60 bundle
ert-IK60kit-desc = IK-60-M bundled together with 4 Laser magazines. Watch your ammo consumption.
ert-jackdawkit-name = Jackdaw bundle
ert-jackdawkit-desc = A caseless rifle, paired with 20 round magazines. Property of Internal Affairs.
ert-GammaC4-name = C4 box
ert-GammaC4-desc = 4 timed charges of plastic breaching explosives.
@@ -1,207 +0,0 @@
marking-ThavenHairAfro = Afro
marking-ThavenHairAfro2 = Afro 2
marking-ThavenHairBigafro = Afro (Large)
marking-ThavenHairAntenna = Ahoge
marking-ThavenHairBalding = Balding Hair
marking-ThavenHairBedhead = Bedhead
marking-ThavenHairBedheadv2 = Bedhead 2
marking-ThavenHairBedheadv3 = Bedhead 3
marking-ThavenHairLongBedhead = Long Bedhead
marking-ThavenHairLongBedhead2 = Long Bedhead 2
marking-ThavenHairFloorlengthBedhead = Floorlength Bedhead
marking-ThavenHairBeehive = Beehive
marking-ThavenHairBeehive2 = Beehive 2
marking-ThavenHairBob = Bob Hair
marking-ThavenHairBob2 = Bob Hair 2
marking-ThavenHairBobcut = Bob Hair 3
marking-ThavenHairBob4 = Bob Hair 4
marking-ThavenHairBob5 = Bob Hair 5
marking-ThavenHairBobcurl = Bobcurl
marking-ThavenHairBoddicker = Boddicker
marking-ThavenHairBowlcut = Bowlcut
marking-ThavenHairBowlcut2 = Bowlcut 2
marking-ThavenHairBraid = Braid (Floorlength)
marking-ThavenHairBraided = Braided
marking-ThavenHairBraidfront = Braided Front
marking-ThavenHairBraid2 = Braid (High)
marking-ThavenHairHbraid = Braid (Low)
marking-ThavenHairShortbraid = Braid (Short)
marking-ThavenHairBraidtail = Braided Tail
marking-ThavenHairBun = Bun Head
marking-ThavenHairBunhead2 = Bun Head 2
marking-ThavenHairBun3 = Bun Head 3
marking-ThavenHairLargebun = Bun (Large)
marking-ThavenHairManbun = Bun (Manbun)
marking-ThavenHairTightbun = Bun (Tight)
marking-ThavenHairBusiness = Business Hair
marking-ThavenHairBusiness2 = Business Hair 2
marking-ThavenHairBusiness3 = Business Hair 3
marking-ThavenHairBusiness4 = Business Hair 4
marking-ThavenHairBuzzcut = Buzzcut
marking-ThavenHairCia = CIA
marking-ThavenHairClassicAfro = Classic Afro
marking-ThavenHairClassicBigAfro = Classic Big Afro
marking-ThavenHairClassicBusiness = Classic Business Hair
marking-ThavenHairClassicciaBusiness = Classic CIA
marking-ThavenHairClassicCornrows = Classic Cornrows
marking-ThavenHairClassicCornrows2 = Classic Cornrows 2
marking-ThavenHairClassicFloorlengthBedhead = Classic Floorlength Bedhead
marking-ThavenHairClassicLong2 = Classic Long Hair 2
marking-ThavenHairClassicLong3 = Classic Long Hair 3
marking-ThavenHairClassicModern = Classic Modern
marking-ThavenHairClassicMulder = Classic Mulder
marking-ThavenHairClassicWisp = Classic Wisp
marking-ThavenHairCoffeeHouse = Coffee House
marking-ThavenHairCombover = Combover
marking-ThavenHairCornrows = Cornrows
marking-ThavenHairCornrows2 = Cornrows 2
marking-ThavenHairCornrowbun = Cornrow Bun
marking-ThavenHairCornrowbraid = Cornrow Braid
marking-ThavenHairCornrowtail = Cornrow Tail
marking-ThavenHairCrewcut = Crewcut
marking-ThavenHairCrewcut2 = Crewcut 2
marking-ThavenHairCurls = Curls
marking-ThavenHairC = Cut Hair
marking-ThavenHairDandypompadour = Dandy Pompadour
marking-ThavenHairDevilock = Devil Lock
marking-ThavenHairDoublebun = Double Bun
marking-ThavenHairDoublebunLong = Double Bun Long
marking-ThavenHairDreads = Dreadlocks
marking-ThavenHairDrillHair = Drill Hair
marking-ThavenHairDrillruru = Drillruru
marking-ThavenHairDrillhairextended = Drill Hair (Extended)
marking-ThavenHairEmo = Emo
marking-ThavenHairEmo2 = Emo2
marking-ThavenHairLongeremo = Longer Emo
marking-ThavenHairEmofringe = Emo Fringe
marking-ThavenHairNofade = Fade (None)
marking-ThavenHairHighfade = Fade (High)
marking-ThavenHairMedfade = Fade (Medium)
marking-ThavenHairLowfade = Fade (Low)
marking-ThavenHairBaldfade = Fade (Bald)
marking-ThavenHairFeather = Feather
marking-ThavenHairFather = Father
marking-ThavenHairSargeant = Flat Top
marking-ThavenHairFlair = Flair
marking-ThavenHairBigflattop = Flat Top (Big)
marking-ThavenHairFlow = Flow Hair
marking-ThavenHairGelled = Gelled Back
marking-ThavenHairGentle = Gentle
marking-ThavenHairHalfbang = Half-banged Hair
marking-ThavenHairHalfbang2 = Half-banged Hair 2
marking-ThavenHairHalfshaved = Half-shaved
marking-ThavenHairHedgehog = Hedgehog Hair
marking-ThavenHairHimecut = Hime Cut
marking-ThavenHairHimecut2 = Hime Cut 2
marking-ThavenHairShorthime = Hime Cut (Short)
marking-ThavenHairHimeup = Hime Updo
marking-ThavenHairHitop = Hitop
marking-ThavenHairJade = Jade
marking-ThavenHairJensen = Jensen Hair
marking-ThavenHairJoestar = Joestar
marking-ThavenHairKeanu = Keanu Hair
marking-ThavenHairKusanagi = Kusanagi Hair
marking-ThavenHairLongBow = Long Bow
marking-ThavenHairLong = Long Hair 1
marking-ThavenHairLong2 = Long Hair 2
marking-ThavenHairLong3 = Long Hair 3
marking-ThavenHairLongWithBundles = Long With Bundles
marking-ThavenHairLongovereye = Long Over Eye
marking-ThavenHairLbangs = Long Bangs
marking-ThavenHairLongemo = Long Emo
marking-ThavenHairLongfringe = Long Fringe
marking-ThavenHairLongsidepart = Long Side Part
marking-ThavenHairMediumSidepart = Medium Side Part
marking-ThavenHairMegaeyebrows = Mega Eyebrows
marking-ThavenHairMessy = Messy
marking-ThavenHairModern = Modern
marking-ThavenHairMohawk = Mohawk
marking-ThavenHairNitori = Nitori
marking-ThavenHairReversemohawk = Mohawk (Reverse)
marking-ThavenHairUnshavenMohawk = Mohawk (Unshaven)
marking-ThavenHairMulder = Mulder
marking-ThavenHairOdango = Odango
marking-ThavenHairOmbre = Ombre
marking-ThavenHairOneshoulder = One Shoulder
marking-ThavenHairShortovereye = Over Eye
marking-ThavenHairOxton = Oxton
marking-ThavenHairParted = Parted
marking-ThavenHairPart = Parted (Side)
marking-ThavenHairKagami = Pigtails
marking-ThavenHairPigtails = Pigtails 2
marking-ThavenHairPigtails2 = Pigtails 3
marking-ThavenHairPixie = Pixie Cut
marking-ThavenHairPompadour = Pompadour
marking-ThavenHairBigpompadour = Pompadour (Big)
marking-ThavenHairPonytail = Ponytail
marking-ThavenHairPonytail2 = Ponytail 2
marking-ThavenHairPonytail3 = Ponytail 3
marking-ThavenHairPonytail4 = Ponytail 4
marking-ThavenHairPonytail5 = Ponytail 5
marking-ThavenHairPonytail6 = Ponytail 6
marking-ThavenHairPonytail7 = Ponytail 7
marking-ThavenHairHighponytail = Ponytail (High)
marking-ThavenHairStail = Ponytail (Short)
marking-ThavenHairLongstraightponytail = Ponytail (Long)
marking-ThavenHairCountry = Ponytail (Country)
marking-ThavenHairFringetail = Ponytail (Fringe)
marking-ThavenHairSidetail = Ponytail (Side)
marking-ThavenHairSidetail2 = Ponytail (Side) 2
marking-ThavenHairSidetail3 = Ponytail (Side) 3
marking-ThavenHairSidetail4 = Ponytail (Side) 4
marking-ThavenHairSpikyponytail = Ponytail (Spiky)
marking-ThavenHairPoofy = Poofy
marking-ThavenHairBald = Bald
marking-ThavenHairClassicCia = Classic CIA
marking-ThavenHairQuiff = Quiff
marking-ThavenHairRonin = Ronin
marking-ThavenHairShaped = Shaped
marking-ThavenHairShaved = Shaved
marking-ThavenHairShavedMohawk = Shaved Mohawk
marking-ThavenHairShavedpart = Shaved Part
marking-ThavenHairShortbangs = Short Bangs
marking-ThavenHairA = Short Hair
marking-ThavenHairShorthair2 = Short Hair 2
marking-ThavenHairShorthair3 = Short Hair 3
marking-ThavenHairShorthair9 = Short Hair 9
marking-ThavenHairD = Short Hair 4
marking-ThavenHairE = Short Hair 5
marking-ThavenHairF = Short Hair 6
marking-ThavenHairShorthairg = Short Hair 7
marking-ThavenHair80s = Short Hair 80s
marking-ThavenHairRosa = Short Hair Rosa
marking-ThavenHairB = Shoulder-length Hair
marking-ThavenHairShoulderLengthOverEye = Shoulder-length Over Eye
marking-ThavenHairSidecut = Sidecut
marking-ThavenHairSkinhead = Skinhead
marking-ThavenHairProtagonist = Slightly Long Hair
marking-ThavenHairSpikey = Spiky
marking-ThavenHairSpiky = Spiky 2
marking-ThavenHairSpiky2 = Spiky 3
marking-ThavenHairSpookyLong = Spooky Long
marking-ThavenHairSwept = Swept Back Hair
marking-ThavenHairSwept2 = Swept Back Hair 2
marking-ThavenHairTailed = Tailed
marking-ThavenHairThinning = Thinning
marking-ThavenHairThinningfront = Thinning (Front)
marking-ThavenHairThinningrear = Thinning (Rear)
marking-ThavenHairTopknot = Topknot
marking-ThavenHairTressshoulder = Tress Shoulder
marking-ThavenHairTrimmed = Trimmed
marking-ThavenHairTrimflat = Trim Flat
marking-ThavenHairTwintail = Twintails
marking-ThavenHairTwoStrands = Two Strands
marking-ThavenHairUndercut = Undercut
marking-ThavenHairUndercutleft = Undercut Left
marking-ThavenHairUndercutright = Undercut Right
marking-ThavenHairUneven = Uneven
marking-ThavenHairUnkept = Unkept
marking-ThavenHairUpdo = Updo
marking-ThavenHairVlong = Very Long Hair
marking-ThavenHairLongest = Very Long Hair 2
marking-ThavenHairLongest2 = Very Long Over Eye
marking-ThavenHairVeryshortovereyealternate = Very Short Over Eye
marking-ThavenHairVlongfringe = Very Long with Fringe
marking-ThavenHairVolaju = Volaju
marking-ThavenHairWisp = Wisp
marking-ThavenHairFrenchbraid = French Braid
@@ -1,27 +0,0 @@
marking-ThavenEars1-ears1 = Small Ears
marking-ThavenEars1 = Small Ears
marking-ThavenEars2-ears2 = Medium Ears
marking-ThavenEars2 = Medium Ears
marking-ThavenEars3-ears3 = Long Ears
marking-ThavenEars3 = Long Ears
marking-ThavenEars4-ears4 = Droopy Ears
marking-ThavenEars4 = Droopy Ears
marking-ThavenPiercings-piercings = Helix Piercing
marking-ThavenPiercings = Helix Piercing
marking-ThavenPiercings2-piercings2 = Hoop Piercing
marking-ThavenPiercings2 = Hoop Piercing
marking-ThavenChestTattoo1-chesttat1 = Back Tattoo
marking-ThavenChestTattoo1 = Back Tattoo
marking-ThavenLArmTattoo1-larmtat1 = Arm Band (Left)
marking-ThavenLArmTattoo1 = Arm Band (Left)
marking-ThavenRArmTattoo1-larmtat1 = Arm Band (Right)
marking-ThavenRArmTattoo1 = Arm Band (Right)
@@ -0,0 +1,877 @@
# Chest
marking-BodyhairThaven = Body Hair
marking-BodyhairThaven-hair = Body Hair
marking-Gills = Gills
marking-Gills-gills = Gills
marking-ThavenAbs = Muscles
marking-ThavenAbs-muscular = Muscles
marking-ThavenBiteMark = Big Bite Scar
marking-ThavenBiteMark-bitemark = Big Bite Scar
marking-ThavenBodyStripes = Pinstripes
marking-ThavenBodyStripes-stripes = Pinstripes
marking-ThavenChestScales = Scales
marking-ThavenChestScales-scales = Scales
marking-ThavenChestTattoo1 = Back Tattoo
marking-ThavenChestTattoo1-tat1 = Back Tattoo
marking-ThavenSpinechill = Spinechill
marking-ThavenSpinechill-spinechill = Spinechill
marking-ThavenSpines = Spines
marking-ThavenSpines-spines = Spines
marking-ThavenTattooWave = Wave Tattoo
marking-ThavenTattooWave-tattoowave = Wave Tattoo
marking-ThavenTattooVines = Vine Tattoo
marking-ThavenTattooVines-tattoovines = Vine Tattoo
marking-ThavenTiger = Tiger Stripes
marking-ThavenTiger-tiger1 = Tiger Belly
marking-ThavenTiger-tiger2 = Tiger Stripes
marking-ThavenTopSurgery = Top Surgery
marking-ThavenTopSurgery-nonaturals = Top Surgery
# Head
marking-ThavenHeadCap = Dappled Crown
marking-ThavenHeadCap-cap1 = Crown
marking-ThavenHeadCap-cap2 = Dapples
marking-ThavenHeadScales = Scales
marking-ThavenHeadScales-scales = Scales
marking-ThavenHeadStripes = Pinstripes
marking-ThavenHeadStripes-stripes = Pinstripes
marking-ThavenShadow = Gloomy
marking-ThavenShadow-shadowthaven = Gloomy
# Snout
# Eyes
marking-SharkminnowEyeliner = Sharkminnow Eyeliner
marking-SharkminnowEyeliner-sharkminnoweyeliner = Sharkminnow Eyeliner
marking-ThavenEyesSharkminnow = Sharkminnow Eyes
marking-ThavenEyesSharkminnow-sharkminnow = Sharkminnow Eyes
marking-ThavenEyesSharkminnowGlowing = Glowing Sharkminnow Eyes
marking-ThavenEyesSharkminnowGlowing-sharkminnow = Glowing Sharkminnow Eyes
marking-ThavenLEyeGlow = Glowing Eye (Left)
marking-ThavenLEyeGlow-glowleft = Glowing Eye (Left)
marking-ThavenREyeGlow = Glowing Eye (Right)
marking-ThavenREyeGlow-glowright = Glowing Eye (Right)
# RArm
marking-ThavenRArmScales = Scales (Right Arm)
marking-ThavenRArmScales-scales = Scales (Right Arm)
marking-ThavenRArmTattoo1 = Arm Band (Right)
marking-ThavenRArmTattoo1-tat1 = Arm Band (Right)
marking-ThavenTigerRArm = Tiger Stripes (Right)
marking-ThavenTigerRArm-tiger = Tiger Stripes (Right)
# LArm
marking-ThavenLArmScales = Scales (Left Arm)
marking-ThavenLArmScales-scales = Scales (Left Arm)
marking-ThavenLArmTattoo1 = Arm Band (Left)
marking-ThavenLArmTattoo1-tat1 = Arm Band (Left)
marking-ThavenTigerLArm = Tiger Stripes (Left)
marking-ThavenTigerLArm-tiger = Tiger Stripes (Left)
# RLeg
marking-ThavenRLegScales = Scales (Right)
marking-ThavenRLegScales-scales = Scales (Right)
# LLeg
marking-ThavenLLegScales = Scales (Left)
marking-ThavenLLegScales-scales = Scales (Left)
# UndergarmentBottom
marking-UnderwearBriefsT = Briefs
marking-UnderwearBriefsT-briefs = Underwear
marking-UnderwearDefaultT = Boxers
marking-UnderwearDefaultT-boxers = Underwear
marking-UnderwearLowridersT = Lowriders
marking-UnderwearLowridersT-lowriders = Underwear
marking-UnderwearSatinT = Satin
marking-UnderwearSatinT-satin = Underwear
marking-UnderwearTangaT = Tanga
marking-UnderwearTangaT-tanga = Underwear
# UndergarmentTop
marking-UndergarmentTopBinderT = Binder
marking-UndergarmentTopBinderT-binder = Binder
marking-UndershirtBraClassicT = Bra
marking-UndershirtBraClassicT-classic = Bra
marking-UndershirtBraSportsT = Bra (Sports)
marking-UndershirtBraSportsT-sports = Bra
marking-UndershirtBraStraplessT = Bra (Strapless)
marking-UndershirtBraStraplessT-strapless = Bra
marking-UndershirtDefaultT = Undershirt
marking-UndershirtDefaultT-undershirt = Undershirt
marking-UndershirtGrossSleevelessT = Tanktop (Gross)
marking-UndershirtGrossSleevelessT-grosssleeveless = Tanktop
marking-UndershirtNanotrasenT = Undershirt (Nanotrasen)
marking-UndershirtNanotrasenT-nanotrasen = Undershirt
marking-UndershirtRolledT = Undershirt (Cropped)
marking-UndershirtRolledT-rolledundershirt = Undershirt
# LFoot
# RFoot
# LHand
# RHand
# FacialHair
# Hair
marking-BurqaSolidThaven = Burqa
marking-BurqaSolidThaven-burqa = Burqa
marking-HairFloralLongThaven = Floral hair (Long)
marking-HairFloralLongThaven-florallong1 = Hair
marking-HairFloralLongThaven-florallong2 = Flowers
marking-HairFloralMidThaven = Floral hair (Medium)
marking-HairFloralMidThaven-floralmid1 = Hair
marking-HairFloralMidThaven-floralmid2 = Flowers
marking-HijabFashionableThaven = Hijab (Fashionable)
marking-HijabFashionableThaven-hijabchic = Hijab (Fashionable)
marking-HijabSimpleThaven = Hijab (Simple)
marking-HijabSimpleThaven-hijabsimple = Hijab (Simple)
marking-MessyPonytailThaven = Messy Ponytail
marking-MessyPonytailThaven-messyponytail = Messy Ponytail
marking-NiqabThaven = Niqab
marking-NiqabThaven-niqab = Niqab
marking-ThavenHair80s = Short Hair 80s
marking-ThavenHair80s-80s = Short Hair 80s
marking-ThavenHairA = Short Hair
marking-ThavenHairA-a = Short Hair
# did anyone else hear just one single angelic note
marking-ThavenHairB = Shoulder-length Hair
marking-ThavenHairB-b = Shoulder-length Hair
marking-ThavenHairBald = Bald
marking-ThavenHairBald-bald = Bald
marking-ThavenHairBaldfade = Fade (Bald)
marking-ThavenHairBaldfade-baldface = Fade (Bald)
marking-ThavenHairBalding = Balding Hair
marking-ThavenHairBalding-e = Balding Hair
marking-ThavenHairBedhead = Bedhead
marking-ThavenHairBedhead-bedhead = Bedhead
marking-ThavenHairBedheadv2 = Bedhead 2
marking-ThavenHairBedheadv2-bedhead2 = Bedhead 2
marking-ThavenHairBedheadv3 = Bedhead 3
marking-ThavenHairBedheadv3-bedhead3 = Bedhead 3
marking-ThavenHairBeehive = Beehive
marking-ThavenHairBeehive-beehive = Beehive
marking-ThavenHairBeehive2 = Beehive 2
marking-ThavenHairBeehive2-beehive2 = Beehive 2
marking-ThavenHairBigflattop = Flat Top (Big)
marking-ThavenHairBigflattop-bigflattop = Flat Top (Big)
marking-ThavenHairBigpompadour = Pompadour (Big)
marking-ThavenHairBigpompadour-bigpompadour = Pompadour (Big)
marking-ThavenHairBob = Bob Hair
marking-ThavenHairBob-bob = Bob Hair
marking-ThavenHairBob2 = Bob Hair 2
marking-ThavenHairBob2-bob2 = Bob Hair 2
marking-ThavenHairBob4 = Bob Hair 4
marking-ThavenHairBob4-bob4 = Bob Hair 4
marking-ThavenHairBob5 = Bob Hair 5
marking-ThavenHairBob5-bob5 = Bob Hair 5
marking-ThavenHairBobcurl = Bobcurl
marking-ThavenHairBobcurl-bobcurl = Bobcurl
marking-ThavenHairBobcut = Bob Hair 3
marking-ThavenHairBobcut-bobcut = Bob Hair 3
marking-ThavenHairBowlcut = Bowlcut
marking-ThavenHairBowlcut-bowlcut = Bowlcut
marking-ThavenHairBowlcut2 = Bowlcut 2
marking-ThavenHairBowlcut2-bowlcut2 = Bowlcut 2
marking-ThavenHairBraid = Braid (Floorlength)
marking-ThavenHairBraid-braid = Braid (Floorlength)
marking-ThavenHairBraid2 = Braid (High)
marking-ThavenHairBraid2-braid2 = Braid (High)
marking-ThavenHairBraided = Braided
marking-ThavenHairBraided-braided = Braided
marking-ThavenHairBraidfront = Braided Front
marking-ThavenHairBraidfront-braidfront = Braided Front
marking-ThavenHairBraidtail = Braided Tail
marking-ThavenHairBraidtail-braidtail = Braided Tail
marking-ThavenHairBun = Bun Head
marking-ThavenHairBun-bun = Bun Head
marking-ThavenHairBun3 = Bun Head 3
marking-ThavenHairBun3-bun3 = Bun Head 3
marking-ThavenHairBunhead2 = Bun Head 2
marking-ThavenHairBunhead2-bunhead2 = Bun Head 2
marking-ThavenHairBusiness = Business Hair
marking-ThavenHairBusiness-business = Business Hair
marking-ThavenHairBusiness2 = Business Hair 2
marking-ThavenHairBusiness2-business2 = Business Hair 2
marking-ThavenHairBusiness3 = Business Hair 3
marking-ThavenHairBusiness3-business3 = Business Hair 3
marking-ThavenHairBusiness4 = Business Hair 4
marking-ThavenHairBusiness4-business4 = Business Hair 4
marking-ThavenHairBuzzcut = Buzzcut
marking-ThavenHairBuzzcut-buzzcut = Buzzcut
marking-ThavenHairC = Cut Hair
marking-ThavenHairC-c = Cut Hair
marking-ThavenHairCia = CIA
marking-ThavenHairCia-cia = CIA
marking-ThavenHairClassicAfro = Classic Afro
marking-ThavenHairClassicAfro-classicafro = Classic Afro
marking-ThavenHairClassicCia = Classic CIA
marking-ThavenHairClassicCia-classiccia = Classic CIA
marking-ThavenHairClassicciaBusiness = Classic CIA Business
marking-ThavenHairClassicciaBusiness-classicciabusiness = Classic CIA Business
marking-ThavenHairClassicCornrows = Classic Cornrows
marking-ThavenHairClassicCornrows-classiccornrows = Classic Cornrows
marking-ThavenHairClassicCornrows2 = Classic Cornrows 2
marking-ThavenHairClassicCornrows2-cornrows2 = Classic Cornrows 2
marking-ThavenHairClassicFloorlengthBedhead = Classic Floorlength Bedhead
marking-ThavenHairClassicFloorlengthBedhead-classicfloorlengthbedhead = Classic Floorlength Bedhead
marking-ThavenHairClassicLong2 = Classic Long Hair 2
marking-ThavenHairClassicLong2-classiclong2 = Classic Long Hair 2
marking-ThavenHairClassicLong3 = Classic Long Hair 3
marking-ThavenHairClassicLong3-classiclong3 = Classic Long Hair 3
marking-ThavenHairClassicModern = Classic Modern
marking-ThavenHairClassicModern-modern = Classic Modern
marking-ThavenHairClassicMulder = Classic Mulder
marking-ThavenHairClassicMulder-classicmulder = Classic Mulder
marking-ThavenHairClassicWisp = Classic Wisp
marking-ThavenHairClassicWisp-classicwisp = Classic Wisp
marking-ThavenHairCoffeeHouse = Coffee House
marking-ThavenHairCoffeeHouse-coffeehouse = Coffee House
marking-ThavenHairCombover = Combover
marking-ThavenHairCombover-combover = Combover
marking-ThavenHairCornrowbraid = Cornrow Braid
marking-ThavenHairCornrowbraid-cornrowbraid = Cornrow Braid
marking-ThavenHairCornrowbun = Cornrow Bun
marking-ThavenHairCornrowbun-cornrowbun = Cornrow Bun
marking-ThavenHairCornrows = Cornrows
marking-ThavenHairCornrows-cornrows = Cornrows
marking-ThavenHairCornrows2 = Cornrows 2
marking-ThavenHairCornrows2-cornrows2 = Cornrows 2
marking-ThavenHairCornrowtail = Cornrow Tail
marking-ThavenHairCornrowtail-cornrowtail = Cornrow Tail
marking-ThavenHairCountry = Ponytail (Country)
marking-ThavenHairCountry-country = Ponytail (Country)
marking-ThavenHairCrewcut = Crewcut
marking-ThavenHairCrewcut-crewcut = Crewcut
marking-ThavenHairCrewcut2 = Crewcut 2
marking-ThavenHairCrewcut2-crewcut2 = Crewcut 2
marking-ThavenHairCurls = Curls
marking-ThavenHairCurls-curls = Curls
marking-ThavenHairDandypompadour = Dandy Pompadour
marking-ThavenHairDandypompadour-dandypompadour = Dandy Pompadour
marking-ThavenHairDevilock = Devil Lock
marking-ThavenHairDevilock-devilock = Devil Lock
marking-ThavenHairDoublebun = Double Bun
marking-ThavenHairDoublebun-doublebun = Double Bun
marking-ThavenHairDoublebunLong = Double Bun Long
marking-ThavenHairDoublebunLong-doublebunlong = Double Bun Long
marking-ThavenHairDreads = Dreadlocks
marking-ThavenHairDreads-dreads = Dreadlocks
marking-ThavenHairDrillHair = Drill Hair
marking-ThavenHairDrillHair-drillhair = Drill Hair
marking-ThavenHairDrillhairextended = Drill Hair (Extended)
marking-ThavenHairDrillhairextended-drillhairextended = Drill Hair (Extended)
marking-ThavenHairDrillruru = Drillruru
marking-ThavenHairDrillruru-drillruru = Drillruru
marking-ThavenHairDyedLong = Dyed Long
marking-ThavenHairDyedLong-dyedlong1 = Dyed Long
marking-ThavenHairDyedShort = Dyed Short
marking-ThavenHairDyedShort-dyedshort1 = Dyed Short
marking-ThavenHairEmo2 = Emo
marking-ThavenHairEmo2-emo2 = Emo
marking-ThavenHairEmofringe = Emo Fringe
marking-ThavenHairEmofringe-emofringe = Emo Fringe
marking-ThavenHairFather = Father
marking-ThavenHairFather-father = Father
marking-ThavenHairFeather = Feather
marking-ThavenHairFeather-feather = Feather
marking-ThavenHairFlair = Flair
marking-ThavenHairFlair-flair = Flair
marking-ThavenHairFloorlengthBedhead = Floorlength Bedhead
marking-ThavenHairFloorlengthBedhead-floorlengthbedhead = Floorlength Bedhead
marking-ThavenHairFlow = Flow Hair
marking-ThavenHairFlow-f = Flow Hair
marking-ThavenHairFrenchbraid = French Braid
marking-ThavenHairFrenchbraid-frenchbraid = French Braid
marking-ThavenHairFringetail = Ponytail (Fringe)
marking-ThavenHairFringetail-fringetail = Ponytail (Fringe)
marking-ThavenHairGelled = Gelled Back
marking-ThavenHairGelled-gelled = Gelled Back
marking-ThavenHairGentle = Gentle
marking-ThavenHairGentle-gentle = Gentle
marking-ThavenHairHalfbang = Half-banged Hair
marking-ThavenHairHalfbang-halfbang = Half-banged Hair
marking-ThavenHairHalfbang2 = Half-banged Hair 2
marking-ThavenHairHalfbang2-halfbang2 = Half-banged Hair 2
marking-ThavenHairHalfshaved = Half-shaved
marking-ThavenHairHalfshaved-halfshaved = Half-shaved
marking-ThavenHairHalfUpLong = Half-Up (Long)
marking-ThavenHairHalfUpLong-halfuplong = Half-Up (Long)
marking-ThavenHairHalfUpShort = Half-Up (Short)
marking-ThavenHairHalfUpShort-halfupshort = Half-Up (Short)
marking-ThavenHairHalfUpUndercut = Half-Up (Undercut)
marking-ThavenHairHalfUpUndercut-halfupundercut = Half-Up (Undercut)
marking-ThavenHairHbraid = Braid (Low)
marking-ThavenHairHbraid-hbraid = Braid (Low)
marking-ThavenHairHedgehog = Hedgehog Hair
marking-ThavenHairHedgehog-hedgehog = Hedgehog Hair
marking-ThavenHairHighfade = Fade (High)
marking-ThavenHairHighfade-highfade = Fade (High)
marking-ThavenHairHighponytail = Ponytail (High)
marking-ThavenHairHighponytail-highponytail = Ponytail (High)
marking-ThavenHairHimecut = Hime Cut
marking-ThavenHairHimecut-himecut = Hime Cut
marking-ThavenHairHimecut2 = Hime Cut 2
marking-ThavenHairHimecut2-himecut2 = Hime Cut 2
marking-ThavenHairHimeup = Hime Updo
marking-ThavenHairHimeup-himeup = Hime Updo
marking-ThavenHairHitop = Hitop
marking-ThavenHairHitop-hitop = Hitop
marking-ThavenHairJade = Jade
marking-ThavenHairJade-jade = Jade
marking-ThavenHairJensen = Jensen Hair
marking-ThavenHairJensen-jensen = Jensen Hair
marking-ThavenHairJoestar = Joestar
marking-ThavenHairJoestar-joestar = Joestar
marking-ThavenHairKagami = Pigtails
marking-ThavenHairKagami-kagami = Pigtails
marking-ThavenHairKeanu = Keanu Hair
marking-ThavenHairKeanu-keanu = Keanu Hair
marking-ThavenHairKusanagi = Kusanagi Hair
marking-ThavenHairKusanagi-kusanagi = Kusanagi Hair
marking-ThavenHairLargebun = Bun (Large)
marking-ThavenHairLargebun-largebun = Bun (Large)
marking-ThavenHairLbangs = Long Bangs
marking-ThavenHairLbangs-lbangs = Long Bangs
marking-ThavenHairLong = Long Hair 1
marking-ThavenHairLong-long = Long Hair 1
marking-ThavenHairLong2 = Long Hair 2
marking-ThavenHairLong2-long2 = Long Hair 2
marking-ThavenHairLong3 = Long Hair 3
marking-ThavenHairLong3-long3 = Long Hair 3
marking-ThavenHairLongBedhead = Long Bedhead
marking-ThavenHairLongBedhead-longbedhead = Long Bedhead
marking-ThavenHairLongBedhead2 = Long Bedhead 2
marking-ThavenHairLongBedhead2-longbedhead2 = Long Bedhead 2
marking-ThavenHairLongeremo = Longer Emo
marking-ThavenHairLongeremo-longeremo = Longer Emo
marking-ThavenHairLongest = Very Long Hair 2
marking-ThavenHairLongest-longest = Very Long Hair 2
marking-ThavenHairLongest2 = Very Long Over Eye
marking-ThavenHairLongest2-longest2 = Very Long Over Eye
marking-ThavenHairLongfringe = Long Fringe
marking-ThavenHairLongfringe-longfringe = Long Fringe
marking-ThavenHairLongovereye = Long Over Eye
marking-ThavenHairLongovereye-longovereye = Long Over Eye
marking-ThavenHairLongsidepart = Long Side Part
marking-ThavenHairLongstraightponytail = Ponytail (Long)
marking-ThavenHairLongstraightponytail-longsidepart = Ponytail (Long)
marking-ThavenHairLongWithBundles = Long With Bundles
marking-ThavenHairLongWithBundles-longbundled = Long With Bundles
marking-ThavenHairLowfade = Fade (Low)
marking-ThavenHairLowfade-lowfade = Fade (Low)
marking-ThavenHairManbun = Bun (Manbun)
marking-ThavenHairManbun-manbun = Bun (Manbun)
marking-ThavenHairMedfade = Fade (Medium)
marking-ThavenHairMedfade-medfade = Fade (Medium)
marking-ThavenHairMediumSidepart = Medium Side Part
marking-ThavenHairMediumSidepart-mediumsidepart = Medium Side Part
marking-ThavenHairMegaeyebrows = Mega Eyebrows
marking-ThavenHairMegaeyebrows-megaeyebrows = Mega Eyebrows
marking-ThavenHairMessy = Messy
marking-ThavenHairMessy-messy = Messy
marking-ThavenHairMidPartLong = Middle Part (Long)
marking-ThavenHairMidPartLong-midpartlong = Middle Part (Long)
marking-ThavenHairMidPartLonger = Middle Part (Longer)
marking-ThavenHairMidPartLonger-midpartlonger = Middle Part (Longer)
marking-ThavenHairModern = Modern
marking-ThavenHairModern-modern = Modern
marking-ThavenHairMohawk = Mohawk
marking-ThavenHairMohawk-d = Mohawk
marking-ThavenHairMulder = Mulder
marking-ThavenHairMulder-mulder = Mulder
marking-ThavenHairMullet = Mullet
marking-ThavenHairMullet-mullet = Mullet
marking-ThavenHairMulletSideshave = Mullet (Sideshave)
marking-ThavenHairMulletSideshave-mulletsideshave = Mullet (Sideshave)
marking-ThavenHairNitori = Nitori
marking-ThavenHairNitori-nitori = Nitori
marking-ThavenHairNofade = Fade (None)
marking-ThavenHairNofade-nofade = Fade (None)
marking-ThavenHairOdango = Odango
marking-ThavenHairOdango-odango = Odango
marking-ThavenHairOmbre = Ombre
marking-ThavenHairOmbre-ombre = Ombre
marking-ThavenHairOneshoulder = One Shoulder
marking-ThavenHairOneshoulder-oneshoulder = One Shoulder
marking-ThavenHairOxton = Oxton
marking-ThavenHairOxton-oxton = Oxton
marking-ThavenHairPart = Parted (Side)
marking-ThavenHairPart-part = Parted (Side)
marking-ThavenHairParted = Parted
marking-ThavenHairParted-parted = Parted
marking-ThavenHairPigtails = Pigtails 2
marking-ThavenHairPigtails-pigtails = Pigtails 2
marking-ThavenHairPigtails2 = Pigtails 3
marking-ThavenHairPigtails2-pigtails2 = Pigtails 3
marking-ThavenHairPixie = Pixie Cut
marking-ThavenHairPixie-pixie = Pixie Cut
marking-ThavenHairPompadour = Pompadour
marking-ThavenHairPompadour-pompadour = Pompadour
marking-ThavenHairPonytail = Ponytail
marking-ThavenHairPonytail-ponytail = Ponytail
marking-ThavenHairPonytail2 = Ponytail 2
marking-ThavenHairPonytail2-ponytail2 = Ponytail 2
marking-ThavenHairPonytail3 = Ponytail 3
marking-ThavenHairPonytail3-ponytail3 = Ponytail 3
marking-ThavenHairPonytail4 = Ponytail 4
marking-ThavenHairPonytail4-ponytail4 = Ponytail 4
marking-ThavenHairPonytail5 = Ponytail 5
marking-ThavenHairPonytail5-ponytail5 = Ponytail 5
marking-ThavenHairPonytail6 = Ponytail 6
marking-ThavenHairPonytail6-ponytail6 = Ponytail 6
marking-ThavenHairPonytail7 = Ponytail 7
marking-ThavenHairPonytail7-ponytail7 = Ponytail 7
marking-ThavenHairPoofy = Poofy
marking-ThavenHairPoofy-poofy = Poofy
marking-ThavenHairProtagonist = Slightly Long Hair
marking-ThavenHairProtagonist-protagonist = Slightly Long Hair
marking-ThavenHairQuiff = Quiff
marking-ThavenHairQuiff-quiff = Quiff
marking-ThavenHairReversemohawk = Mohawk (Reverse)
marking-ThavenHairReversemohawk-reversemohawk = Mohawk (Reverse)
marking-ThavenHairRonin = Ronin
marking-ThavenHairRonin-ronin = Ronin
marking-ThavenHairRosa = Short Hair Rosa
marking-ThavenHairRosa-rosa = Short Hair Rosa
marking-ThavenHairSargeant = Flat Top
marking-ThavenHairSargeant-sargeant = Flat Top
marking-ThavenHairShaved = Shaved
marking-ThavenHairShaved-shaved = Shaved
marking-ThavenHairShavedMohawk = Shaved Mohawk
marking-ThavenHairShavedMohawk-shavedmohawk = Shaved Mohawk
marking-ThavenHairShavedpart = Shaved Part
marking-ThavenHairShavedpart-shavedpart = Shaved Part
marking-ThavenHairShortbangs = Short Bangs
marking-ThavenHairShortbangs-shortbangs = Short Bangs
marking-ThavenHairShortbraid = Braid (Short)
marking-ThavenHairShortbraid-shortbraid = Braid (Short)
marking-ThavenHairShorthair2 = Short Hair 2
marking-ThavenHairShorthair2-shorthair2 = Short Hair 2
marking-ThavenHairShorthair3 = Short Hair 3
marking-ThavenHairShorthair3-shorthair3 = Short Hair 3
marking-ThavenHairShorthair9 = Short Hair 9
marking-ThavenHairShorthair9-shorthair9 = Short Hair 9
marking-ThavenHairShorthime = Hime Cut (Short)
marking-ThavenHairShorthime-shorthime = Hime Cut (Short)
marking-ThavenHairShortovereye = Over Eye
marking-ThavenHairShortovereye-shortovereye = Over Eye
marking-ThavenHairShoulderLengthOverEye = Shoulder-length Over Eye
marking-ThavenHairShoulderLengthOverEye-shoulderlengthovereye = Shoulder-length Over Eye
marking-ThavenHairSidecut = Sidecut
marking-ThavenHairSidecut-sidecut = Sidecut
marking-ThavenHairSideshaveCurly = Sideshave (Curly)
marking-ThavenHairSideshaveCurly-sideshavecurly = Sideshave (Curly)
marking-ThavenHairSidetail = Ponytail (Side)
marking-ThavenHairSidetail-sidetail = Ponytail (Side)
marking-ThavenHairSidetail2 = Ponytail (Side) 2
marking-ThavenHairSidetail2-sidetail2 = Ponytail (Side) 2
marking-ThavenHairSidetail3 = Ponytail (Side) 3
marking-ThavenHairSidetail3-sidetail3 = Ponytail (Side) 3
marking-ThavenHairSidetail4 = Ponytail (Side) 4
marking-ThavenHairSidetail4-sidetail4 = Ponytail (Side) 4
marking-ThavenHairSkinhead = High And Tight
marking-ThavenHairSkinhead-skinhead = High And Tight
marking-ThavenHairSpiky = Spiky 2
marking-ThavenHairSpiky-spiky = Spiky 2
marking-ThavenHairSpikyponytailLong = Ponytail (Spiky Long)
marking-ThavenHairSpikyponytailLong-spikyponytaillong = Ponytail (Spiky Long)
marking-ThavenHairSpikyponytail = Ponytail (Spiky)
marking-ThavenHairSpikyponytail-spikyponytail = Ponytail (Spiky)
marking-ThavenHairSpookyLong = Spooky Long
marking-ThavenHairSpookyLong-spookylong = Spooky Long
marking-ThavenHairStail = Ponytail (Short)
marking-ThavenHairStail-stail = Ponytail (Short)
marking-ThavenHairSwept = Swept Back Hair
marking-ThavenHairSwept-swept = Swept Back Hair
marking-ThavenHairSwept2 = Swept Back Hair 2
marking-ThavenHairSwept2-swept2 = Swept Back Hair 2
marking-ThavenHairTailed = Tailed
marking-ThavenHairTailed-tailed = Tailed
marking-ThavenHairThinning = Thinning
marking-ThavenHairThinning-thinning = Thinning
marking-ThavenHairThinningfront = Thinning (Front)
marking-ThavenHairThinningfront-thinningfront = Thinning (Front)
marking-ThavenHairThinningrear = Thinning (Rear)
marking-ThavenHairThinningrear-thinningrear = Thinning (Rear)
marking-ThavenHairTightbun = Bun (Tight)
marking-ThavenHairTightbun-tightbun = Bun (Tight)
marking-ThavenHairTopknot = Topknot
marking-ThavenHairTopknot-topknot = Topknot
marking-ThavenHairTressshoulder = Tress Shoulder
marking-ThavenHairTressshoulder-tressshoulder = Tress Shoulder
marking-ThavenHairTrimflat = Trim Flat
marking-ThavenHairTrimflat-trimflat = Trim Flat
marking-ThavenHairTrimmed = Trimmed
marking-ThavenHairTrimmed-trimmed = Trimmed
marking-ThavenHairTwintail = Twintails
marking-ThavenHairTwintail-twintail = Twintails
marking-ThavenHairTwoStrands = Two Strands
marking-ThavenHairTwoStrands-twostrands = Two Strands
marking-ThavenHairUndercut = Undercut
marking-ThavenHairUndercut-undercut = Undercut
marking-ThavenHairUndercutCurly = Undercut (Curly)
marking-ThavenHairUndercutCurly-undercutcurly = Undercut (Curly)
marking-ThavenHairUndercutleft = Undercut Left
marking-ThavenHairUndercutleft-undercutleft = Undercut Left
marking-ThavenHairUndercutright = Undercut Right
marking-ThavenHairUndercutright-undercutright = Undercut Right
marking-ThavenHairUneven = Uneven
marking-ThavenHairUneven-uneven = Uneven
marking-ThavenHairUnkept = Unkept
marking-ThavenHairUnkept-unkept = Unkept
marking-ThavenHairVeryshortovereyealternate = Very Short Over Eye
marking-ThavenHairVeryshortovereyealternate-veryshortovereyealternate = Very Short Over Eye
marking-ThavenHairVlong = Very Long Hair
marking-ThavenHairVlong-vlong = Very Long Hair
marking-ThavenHairVlongfringe = Very Long with Fringe
marking-ThavenHairVlongfringe-vlongfringe = Very Long with Fringe
marking-ThavenHairVolaju = Volaju
marking-ThavenHairVolaju-volaju = Volaju
marking-ThavenHairWisp = Wisp
marking-ThavenHairWisp-wisp = Wisp
marking-TichelFashionableThaven = Tichel (Fashionable)
marking-TichelFashionableThaven-tichelfashionable = Tichel (Fashionable)
marking-TichelSimpleThaven = Tichel (Simple)
marking-TichelSimpleThaven-tichelsimple = Tichel (Simple)
marking-ShaggyThaven = Shaggy
marking-ShaggyThaven-shaggythaven = Shaggy
marking-ShaggyLongerThaven = Shaggy (Longer)
marking-ShaggyLongerThaven-shaggylongerthaven = Shaggy (Longer)
marking-SusieThaven = Mean Girl (Bangs)
marking-SusieThaven-susiethaven = Mean Girl (Bangs)
marking-SusieNoBangsThaven = Mean Girl
marking-SusieNoBangsThaven-susienobangsthaven = Mean Girl
# HeadSide
marking-ThavenEars1 = Small Ears
marking-ThavenEars1-ears1 = Small Ears
marking-ThavenEars2 = Medium Ears
marking-ThavenEars2-ears2 = Medium Ears
marking-ThavenEars3 = Long Ears
marking-ThavenEars3-ears3 = Long Ears
marking-ThavenEars4 = Droopy Ears
marking-ThavenEars4-ears4 = Droopy Ears
marking-ThavenEarsBigFins = Big Fins
marking-ThavenEarsBigFins-bigfins = Outer
marking-ThavenEarsBigFins-bigfins2 = Inner
marking-ThavenEarsTwinFins = Twin Fins
marking-ThavenEarsTwinFins-twinfin = Twin Fins
marking-ThavenFishEars = Finned Ears
marking-ThavenFishEars-fishears = Finned Ears
marking-ThavenNoEars = Recolorable ears
marking-ThavenNoEars-noears = For use with head coverings
# HeadTop
marking-ThavenHibiscus = Hibiscus
marking-ThavenHibiscus-hibiscus1 = Petals
marking-ThavenHibiscus-hibiscus2 = Anthers
marking-ThavenPiercings = Helix Piercing
marking-ThavenPiercings-piercings = Helix Piercing
marking-ThavenPiercings2 = Hoop Piercing
marking-ThavenPiercings2-piercings2 = Hoop Piercing
# Tail
marking-ThavenBasicTail = Basic Tail
marking-ThavenBasicTail-basic = Basic Tail
marking-ThavenBigTail = Big Tail
marking-ThavenBigTail-big1 = Tail
marking-ThavenBigTail-big2 = Fin
marking-ThavenTadpoleTail = Tadpole Tail
marking-ThavenTadpoleTail-tadpole1 = Tail
marking-ThavenTadpoleTail-tadpole2 = Fin
marking-ThavenTailEel = Eel Tail
marking-ThavenTailEel-eel1 = Eel Tail Trunk
marking-ThavenTailEel-eel2 = Eel Tail Tip
marking-ThavenTailEelOverlay = Eel Tail (Overlay)
marking-ThavenTailEelOverlay-eel3 = Eel Inner
marking-ThavenTailEelOverlay-eel4 = Eel Outer
marking-ThavenTailNurse = Swept Tail
marking-ThavenTailNurse-nurse1 = Tail
marking-ThavenTailNurse-nurse2 = Stripes
marking-ThavenTailStub = Stub Tail
marking-ThavenTailStub-stub1 = Tail
marking-ThavenTailStub-stub2 = Stripes
marking-ThavenTailThresher = Thresher Tail
marking-ThavenTailThresher-thresher1 = Tail
marking-ThavenTailThresher-thresher2 = Stripes
# RArmExtension
@@ -1,3 +0,0 @@
alert-level-orange = Orange
alert-level-orange-announcement = There is a critical station-wide structural or atmospheric threat and recovery is unlikely. Engineering staff are advised to minimize hazards and secure the Evacuation Dock. Crewmembers are advised to stay away from hazardous areas, and prepare for Evacuation. MAYDAY signals have been activated
alert-level-orange-instructions = Avoid hazards and prepare for Evacuation.
@@ -0,0 +1,12 @@
hand-labeler-saved-labels = Saved Labels:
# The text on the button in the ui to save a label to the saved label list.
hand-labeler-save-label-text = Save Label
# The text on the button in the ui to delete a label from the saved label list.
hand-labeler-delete-label-text = Delete Label
# The text on the button when in delete mode.
hand-labeler-delete-mode-text = Deleting...
@@ -45,3 +45,7 @@ alert-level-octarine = Octarine
alert-level-octarine-announcement = A cataclysmic noospheric event threatens to envelop realspace. Station crew are to contain the event if possible, or else evacuate.
alert-level-octarine-instructions = Crewmembers are advised to listen to heads of staff for more information.
## DeltaV - Zeta
alert-level-zeta = Zeta
alert-level-zeta-announcement = The station is unrecoverable, and all important assets and crewmembers are to be evacuated. A distress signal has been sent to all nearby vessels. Security and Engineering staff are advised to minimize hazards and secure the Evacuation Dock. Crewmembers are advised to disembark the station by any means necessary. Godspeed.
alert-level-zeta-instructions = Avoid hazards and prepare for Evacuation.
@@ -1 +1,2 @@
comp-label-format = {$baseName} ({$label})
# Coyote: reverse order of label and baseName
comp-label-format = {$label} ({$baseName})
@@ -180,6 +180,9 @@ uplink-encryption-key-desc = Two encryption keys for access to the secret freque
uplink-binary-translator-key-name = Binary Translator Key
uplink-binary-translator-key-desc = Lets you tap into the silicons' binary channel. Don't talk on it though, at least not without a voice mask.
uplink-freelance-encryption-key-name = Freelancer Encryption Key
uplink-freelance-encryption-key-desc = Lets you access freelancer communications. Perhaps you can find a criminal who will help you for the right price.
uplink-hypopen-name = Hypopen
uplink-hypopen-desc = A chemical hypospray disguised as a pen, capable of instantly injecting up to 10u of reagents. Starts empty.
@@ -358,9 +361,6 @@ uplink-chameleon-desc = A backpack full of items that contain chameleon technolo
uplink-clothing-no-slips-shoes-name = No-slip Shoes
uplink-clothing-no-slips-shoes-desc = Chameleon shoes that protect you from slips.
uplink-clothing-chameleon-thieving-gloves-name = Chameleon Thieving Gloves
uplink-clothing-chameleon-thieving-gloves-desc = Discreetly steal from pockets and improve your thieving technique with these fancy new gloves. They can change appearance to match any pair of gloves!
uplink-clothing-outer-vest-web-name = Web Vest
uplink-clothing-outer-vest-web-desc = A synthetic armor vest. This one has added webbing and ballistic plates.
File diff suppressed because it is too large Load Diff
@@ -97,7 +97,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: Gravity
gravityShakeSound: !type:SoundPathSpecifier
path: /Audio/Effects/alert.ogg
@@ -77,7 +77,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: Gravity
gravityShakeSound: !type:SoundPathSpecifier
path: /Audio/Effects/alert.ogg
@@ -90,7 +90,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: DecalGrid
chunkCollection:
version: 2
@@ -64,7 +64,7 @@ entities:
- type: DeviceNetwork
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
deviceNetId: Wireless
- type: DecalGrid
chunkCollection:
@@ -88,7 +88,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: DecalGrid
chunkCollection:
version: 2
@@ -76,7 +76,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: ImplicitRoof
- type: GridPathfinding
- type: Gravity
@@ -71,7 +71,7 @@ entities:
- type: DeviceNetwork
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
deviceNetId: Wireless
- type: DecalGrid
chunkCollection:
@@ -95,7 +95,7 @@ entities:
- type: DeviceNetwork
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: DecalGrid
chunkCollection:
version: 2
@@ -78,7 +78,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: DecalGrid
chunkCollection:
version: 2
@@ -69,7 +69,7 @@ entities:
- type: DeviceNetwork
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
deviceNetId: Wireless
- type: DecalGrid
chunkCollection:
@@ -109,7 +109,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: DecalGrid
chunkCollection:
version: 2
@@ -97,7 +97,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: DecalGrid
chunkCollection:
version: 2
@@ -85,7 +85,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: DecalGrid
chunkCollection:
version: 2
@@ -75,7 +75,7 @@ entities:
- type: DeviceNetwork
configurators: [ ]
deviceLists: [ ]
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
deviceNetId: Wireless
- type: GridPathfinding
- type: DecalGrid
@@ -126,7 +126,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: GridPathfinding
- type: DecalGrid
chunkCollection:
@@ -94,7 +94,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: DecalGrid
chunkCollection:
version: 2
@@ -75,7 +75,7 @@ entities:
- type: DeviceNetwork
configurators: [ ]
deviceLists: [ ]
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
deviceNetId: Wireless
- type: GridPathfinding
- type: DecalGrid
@@ -81,7 +81,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: Gravity
gravityShakeSound: !type:SoundPathSpecifier
path: /Audio/Effects/alert.ogg
@@ -73,7 +73,7 @@ entities:
deviceNetId: Wireless
configurators: []
deviceLists: []
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet
- type: DecalGrid
chunkCollection:
version: 2
+89645 -41311
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -28978,8 +28978,6 @@ entities:
- type: Transform
pos: 12.5,39.5
parent: 8
- type: CommunicationsConsole
announcementCooldownRemaining: -0.0166666
- proto: ComputerCrewMonitoring
entities:
- uid: 678
+5 -1
View File
@@ -252,5 +252,9 @@ BoxPerformer: BoxPerformerDV
SpawnPointMedicalBorg: SpawnPointBorg
SpawnPointSecurityBorg: SpawnPointBorg
# 2026-06-02
Screen: StatusDisplay
ArrivalsShuttleTimer: StatusDisplayShuttle
# 2026-08-10
BookSecretDocuments: BookMedicalDocuments
BookSecretDocuments: BookMedicalDocuments
+1
View File
@@ -87,6 +87,7 @@
params:
volume: 5
priority: -12
useDelay: 5 # DeltaV - small cooldown
- type: TargetAction
checkCanAccess: false
range: 0
@@ -43,17 +43,6 @@
emergencyLightColor: Red
forceEnableEmergencyLights: true
shuttleTime: 600 #No reduction in time as we don't have swiping for red alert like in /tg/. Shuttle times are intended to create friction, so having a way to brainlessly bypass that would be dumb.
# Begin Starlight Additions
orange:
announcement: alert-level-orange-announcement
selectable: true
sound:
path: /Audio/_Starlight/misc/orange.ogg
color: "#ff8119"
emergencyLightColor: "#ff8119"
forceEnableEmergencyLights: true
shuttleTime: 480
# End Starlight Additions
gamma:
announcement: alert-level-gamma-announcement
selectable: false
@@ -90,3 +79,13 @@
emergencyLightColor: CadetBlue
forceEnableEmergencyLights: true
shuttleTime: 600
zeta: # DeltaV - zeta
announcement: alert-level-zeta-announcement
selectable: false
disableSelection: true
sound:
path: /Audio/_DV/Announcements/Alerts/code_zeta.ogg
color: "#fe8401"
emergencyLightColor: "#fe8401"
forceEnableEmergencyLights: true
shuttleTime: 480
@@ -447,5 +447,5 @@
storagebase: !type:AllSelector
children:
- id: WeaponShotgunHushpup
- id: BoxLethalshot
- id: BoxShellCaseless # DeltaV switched default to caseless shells
- id: TreasureCoinIron
@@ -142,6 +142,7 @@
ClothingUniformBrownSuitSkirt: 2
ClothingShoesLeather: 2
ClothingShoesBootsLaceup: 2
ClothingShoesBootsSurplus: 3
# End DeltaV additions
contrabandInventory:
ClothingMaskNeckGaiter: 2
@@ -1783,21 +1783,6 @@
categories:
- UplinkWearables
# DeltaV - add back thieving gloves
- type: listing
id: UplinkgClothingThievingGloves
name: uplink-clothing-chameleon-thieving-gloves-name
description: uplink-clothing-chameleon-thieving-gloves-desc
productEntity: ClothingHandsChameleonThief
discountCategory: veryRareDiscounts
discountDownTo:
Telecrystal: 4 # DeltaV - was 3
cost:
Telecrystal: 7 # DeltaV - Was 5, 5TC was too cheap for the items power
categories:
- UplinkWearables
# DeltaV - end of changes
- type: listing
id: UplinkClothingOuterVestWeb
name: uplink-clothing-outer-vest-web-name
@@ -176,6 +176,7 @@
- id: GoldenBikeHorn
- id: ClothingHeadHatCatEars
- id: GoldenPersonalAI
- id: UnstableReactorCore # DeltaV
- id: TreasureCoinDiamond
amount: !type:RangeNumberSelector
range: 2, 5
@@ -57,8 +57,12 @@
interfaces:
enum.SolarControlConsoleUiKey.Key:
type: SolarControlConsoleBoundUserInterface
enum.CommunicationsConsoleUiKey.Key:
type: CommunicationsConsoleBoundUserInterface
# BEGIN DeltaV - our own thing
#enum.CommunicationsConsoleUiKey.Key:
# type: CommunicationsConsoleBoundUserInterface
enum.DVCommunicationsConsoleUi.Key:
type: DVCommunicationsConsoleBoundUserInterface
# END DeltaV
enum.RadarConsoleUiKey.Key:
type: RadarConsoleBoundUserInterface
enum.CargoConsoleUiKey.Orders:
@@ -76,7 +80,8 @@
uis:
enum.SolarControlConsoleUiKey.Key:
toggleAction: ActionAGhostShowSolar
enum.CommunicationsConsoleUiKey.Key:
#enum.CommunicationsConsoleUiKey.Key: # DeltaV - comms console
enum.DVCommunicationsConsoleUi.Key: # DeltaV - comms console
toggleAction: ActionAGhostShowCommunications
enum.RadarConsoleUiKey.Key:
toggleAction: ActionAGhostShowRadar
@@ -91,12 +96,22 @@
toggleAction: ActionAGhostShowCharacterRecords
# End CD - Character Records
- type: SolarControlConsole # look ma i AM the computer!
- type: CommunicationsConsole
title: comms-console-announcement-title-centcom
color: "#1d8bad"
delay: 10
initialDelay: 0
global: true
# Begin DeltaV - our own thing
#- type: CommunicationsConsole
# title: comms-console-announcement-title-centcom
# color: "#1d8bad"
# delay: 10
# initialDelay: 0
# global: true
- type: DVCommunicationsConsole
announcementTitle: comms-console-announcement-title-centcom
announcementColor: "#1d8bad"
canAlertLevel: true
canCallShuttles: true
canConfigureScreens: false
canKeycardAuthenticationDevice: false
globalAnnouncements: true
# End DeltaV
- type: RadarConsole
followEntity: true
- type: CargoOrderConsole
@@ -112,7 +127,7 @@
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: NTNet # DeltaV - NTNet
transmitFrequencyId: ShuttleTimer
transmitFrequencyId: NTNet # DeltaV - DVComms Console
- type: WirelessNetworkConnection
range: 10000 # DeltaV
#- type: StationLimitedNetwork # DeltaV - Off-station coordinates
@@ -164,7 +179,7 @@
keywords: [ "AI", "console", "interface" ]
priority: -4
- type: InstantAction
event: !type:ToggleIntrinsicUIEvent { key: enum.CommunicationsConsoleUiKey.Key }
event: !type:ToggleIntrinsicUIEvent { key: enum.DVCommunicationsConsoleUi.Key } # DeltaV - was enum.CommunicationsConsoleUiKey.Key
- type: entity
parent: BaseAGhostAction
@@ -58,8 +58,12 @@
type: GeneralStationRecordConsoleBoundUserInterface
enum.SiliconLawsUiKey.Key:
type: SiliconLawBoundUserInterface
enum.CommunicationsConsoleUiKey.Key:
type: CommunicationsConsoleBoundUserInterface
# BEGIN DeltaV - comms console rework
#enum.CommunicationsConsoleUiKey.Key:
# type: CommunicationsConsoleBoundUserInterface
enum.DVCommunicationsConsoleUi.Key:
type: DVCommunicationsConsoleBoundUserInterface
# END DeltaV
enum.StoreUiKey.Key: # DeltaV - AI shop system
type: StoreBoundUserInterface
# Begin DeltaV - AI PDAs
@@ -80,7 +84,8 @@
toggleAction: ActionAGhostShowCrewMonitoring
enum.GeneralStationRecordConsoleKey.Key:
toggleAction: ActionAGhostShowStationRecords
enum.CommunicationsConsoleUiKey.Key:
#enum.CommunicationsConsoleUiKey.Key: # DeltaV - comms console
enum.DVCommunicationsConsoleUi.Key: # DeltaV - comms console
toggleAction: ActionAGhostShowCommunications
# Begin DeltaV - AI fax
enum.FaxUiKey.Key:
@@ -94,10 +99,20 @@
transmitFrequencyId: NTNet # DeltaV
- type: RadarConsole
followEntity: false
- type: CommunicationsConsole
canShuttle: false
title: comms-console-announcement-title-station-ai
color: "#5ed7aa"
# BEGIN DeltaV - our own thing
#- type: CommunicationsConsole
# canShuttle: false
# title: comms-console-announcement-title-station-ai
# color: "#5ed7aa"
- type: DVCommunicationsConsole
announcementTitle: comms-console-announcement-title-station-ai
announcementColor: "#5ed7aa"
canAlertLevel: true
canCallShuttles: false
canConfigureScreens: true
canKeycardAuthenticationDevice: false
globalAnnouncements: true
# END DeltaV
- type: ShowJobIcons
#- type: ShowCrewIcons # DeltaV - Disable crew icons
- type: DamagedSiliconAccent
@@ -485,6 +485,7 @@
- type: Tag
tags:
- Beer
- DrinkBottle # DeltaV
- type: entity
parent: [DrinkVisualsAllFilled, DrinkBottleGlassSmallBaseFull]
@@ -241,6 +241,7 @@
- Rootsong
- type: TypingIndicator
proto: diona
- type: BlockMovement # They should never be moving!
# DeltaV end
- type: entity
@@ -45,4 +45,5 @@
# Begin DeltaV additions - Disallows recharging of superweapons
- GamblagatorCartridge
- BeamDevastator
- UnstableCoreRefractor
# End DeltaV additions - Disallows recharging of superweapons

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