diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 3759eb70..a60b50b4 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -27,7 +27,7 @@ General Development - [Codebase Organization](en/general-development/codebase-info/codebase-organization.md) - [Acronyms & Nomenclature](en/general-development/codebase-info/acronyms-and-nomenclature.md) - [Tips](en/general-development/tips.md) - - [Beginner FAQ](en/general-development/tips/beginner-faq.md) + - [Beginner FAQ](en/general-development/tips/beginner-faq.md) - [Troubleshooting FAQ](en/general-development/tips/troubleshooting-faq.md) - [Debugging Tools](en/general-development/tips/debugging-tools.md) - [PRs With Engine Changes](en/general-development/tips/prs-with-engine-changes.md) @@ -51,7 +51,7 @@ SS14 By Example - [Porting Appearance Visualizers](en/ss14-by-example/making-a-sprite-dynamic/porting-appearance-visualizers.md) - [Basic Networking and You](en/ss14-by-example/basic-networking-and-you.md) - [Fluent and Localization](en/ss14-by-example/fluent-and-localization.md) -- [UI Survival Guide](en/ss14-by-example/ui-survival-guide.md) +- [UI Survival Guide](en/ss14-by-example/ui-survival-guide.md) Robust Toolbox @@ -77,6 +77,7 @@ Robust Toolbox - [Entities](en/robust-toolbox/toolshed/commands/entity-control.md) - [General](en/robust-toolbox/toolshed/commands/general.md) - [Miscellaneous](en/robust-toolbox/toolshed/commands/misc.md) + - [Toolshed Examples](en/robust-toolbox/toolshed/toolshed-examples.md) - [User Interface](en/robust-toolbox/user-interface.md) - [IoC](en/robust-toolbox/ioc.md) - [Rendering]() @@ -113,6 +114,7 @@ Space Station 14 - [Displacement Maps](en/space-station-14/art/displacement-maps.md) - [Device Network](en/space-station-14/core-tech/device-network.md) - [NPCs](en/space-station-14/core-tech/npcs.md) + - [Entity Tables](en/space-station-14/core-tech/entity-tables.md) - [Chemistry](en/space-station-14/core-tech/chemistry.md) - [Metabolism](en/space-station-14/core-tech/chemistry/metabolism.md) - [Reactions](en/space-station-14/core-tech/chemistry/reactions.md) @@ -185,6 +187,7 @@ Space Station 14 - [Pizza Delivery Critter](en/space-station-14/round-flow/proposals/pizza-delivery-critter.md) - [Rogue Drones](en/space-station-14/round-flow/proposals/rogue-drones.md) - [Turf War](en/space-station-14/round-flow/proposals/turf-war.md) + - [Changeling](en/space-station-14/round-flow/proposals/changeling.md) - [User Interface](en/space-station-14/user-interface.md) - [PR Guidelines](en/space-station-14/user-interface/guidelines.md) @@ -303,7 +306,6 @@ Community - [Discord Rich Presence Repository](en/community/discord-rich-presence-repository.md) - [Project Manager](en/community/projectmanager.md) - [Maintainer](en/community/maintainer.md) - - [Maintainer Policy](en/community/maintainer/wizards-den-maintainer-policy.md) - [Review Policy](en/community/maintainer/wizards-den-review-policy.md) - [Admin](en/community/admin.md) - [Admin Tooling](en/community/admin/admin-tooling.md) diff --git a/src/en/assets/misc/role_hierarchy.xml b/src/en/assets/misc/role_hierarchy.xml index 26db99b7..8fdc74a5 100644 --- a/src/en/assets/misc/role_hierarchy.xml +++ b/src/en/assets/misc/role_hierarchy.xml @@ -1,116 +1,106 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/en/community/maintainer/wizards-den-maintainer-policy.md b/src/en/community/maintainer/wizards-den-maintainer-policy.md deleted file mode 100644 index 2d68c8c9..00000000 --- a/src/en/community/maintainer/wizards-den-maintainer-policy.md +++ /dev/null @@ -1,5 +0,0 @@ -# Wizards Den Maintainer Policy - -```admonish warning "Work in Progress" -This page is a work in progress! Maintainer policy will be posted when they are ready. -``` \ No newline at end of file diff --git a/src/en/community/space-wizards-maintainer-list.md b/src/en/community/space-wizards-maintainer-list.md index 2c5064b4..e3693555 100644 --- a/src/en/community/space-wizards-maintainer-list.md +++ b/src/en/community/space-wizards-maintainer-list.md @@ -37,7 +37,8 @@ Content Maintainers: - [TheShuEd](https://github.com/TheShuEd) - @eshhhed (267327466060775425) - [EmoGarbage404](https://github.com/EmoGarbage404) - @emogarbage (500128901805244436) - [LankLTE](https://github.com/LankLTE) - @lanklte (328292818265047041) -- [Plykiya](https://github.com/Plykiya) - @plykiya (126071710712594432) +- [slarticodefast](https://github.com/slarticodefast) - @sebseb5071 (578191477839101967) +- [UbaserB](https://github.com/UbaserB) - @ubaser (578881480386805771) Engine maintainers: No one maintains only engine :p diff --git a/src/en/community/space-wizards-role-hierarchy.md b/src/en/community/space-wizards-role-hierarchy.md index 7c41b7d7..ccb39241 100644 --- a/src/en/community/space-wizards-role-hierarchy.md +++ b/src/en/community/space-wizards-role-hierarchy.md @@ -2,6 +2,6 @@ -The XML for this diagram is available [here](../assets/misc/role_hierarchy.xml). You can edit it by going to [draw.io](https://app.diagrams.net/), going to `File -> Import from -> Device`, then selecting the file. You should export by going to `File -> Embed -> HTML`. You should also update the [XML](../assets/misc/role_hierarchy.xml) by going to `File -> Export as -> XML`. +The XML for this diagram is available [here](../assets/misc/role_hierarchy.xml). You can edit it by going to [draw.io](https://app.diagrams.net/), going to `File -> Import from -> Device`, then selecting the file. You should export by going to `File -> Embed -> SVG`. You should also update the [XML](../assets/misc/role_hierarchy.xml) by going to `File -> Export as -> XML`. -
Wizard
Project Manager
SS14
Maintainer
Experienced Contributor
Contributor
Inactive Contributor
Game Admin
Trial Admin
Head Game Admin
Moderator
RobustToolbox
Maintainer
Head Mapper
Junior Maintainer
Art Director
\ No newline at end of file +
Wizard
Wizard
Project Manager
Project Manager
SS14
Maintainer
SS14...
Experienced Contributor
Experienced Contribu...
Contributor
Contributor
Inactive Contributor
Inactive Contributor
Game Admin
Game Admin
Trial Admin
Trial Admin
Head Game Admin
Head Game Admin
Moderator
Moderator
RobustToolbox
Maintainer
RobustToolbox...
Head Mapper
Head Mapper
Art Director
Art Director
Text is not SVG - cannot display
\ No newline at end of file diff --git a/src/en/general-development/codebase-info/pull-request-guidelines.md b/src/en/general-development/codebase-info/pull-request-guidelines.md index 2b7e2ae3..b3c45dc8 100644 --- a/src/en/general-development/codebase-info/pull-request-guidelines.md +++ b/src/en/general-development/codebase-info/pull-request-guidelines.md @@ -85,6 +85,34 @@ Each entry is either an `add`, `remove`, `tweak`, or `fix`. There can be multipl Maintainers may, at their discretion, add, modify, or remove a change log entry that you suggest. +#### Admin changelog + +Putting `ADMIN:` in the changelog will place all changelogs below it into the admin changelog category instead of the main changelog category. + +Note: The category is case-insensitive, but if it is not alphabetical ending with a colon, it will fail parsing the category and will fall back to placing the changelogs in the previous category or the main changelog category. + +``` +:cl: +ADMIN: +- add: Added fun! +- remove: Removed fun! +- tweak: Changed fun! +- fix: Fixed fun! +``` +or +``` +:cl: +- add: Added fun! +- remove: Removed fun! +- tweak: Changed fun! +- fix: Fixed fun! +ADMIN: +- add: Added fun! +- remove: Removed fun! +- tweak: Changed fun! +- fix: Fixed fun! +``` + ## Writing An Effective Changelog The Changelog is for *players* to be aware of new features and changes that could affect how they play the game. It is *not* designed for maintainers, admins, or server operators (these should be in the PR description). diff --git a/src/en/general-development/setup/git-for-the-ss14-developer.md b/src/en/general-development/setup/git-for-the-ss14-developer.md index a13b4748..c50dc7c3 100644 --- a/src/en/general-development/setup/git-for-the-ss14-developer.md +++ b/src/en/general-development/setup/git-for-the-ss14-developer.md @@ -34,6 +34,10 @@ While you're here, install `Python 3.7+` as well if you don't have it already. Y
+```admonish danger "Name and Email privacy" +When [setting up your `user.name` and `user.email`](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup#_your_identity), know that these are publicly displayed on all commits that you create. If you want to keep your information private, you can set `user.name` to your username instead of your real name, and `user.email` to the one provided by GitHub when the [`Keep my email addresses private`](https://github.com/settings/emails#toggle_visibility) setting is checked in [GitHub Email Settings](https://github.com/settings/emails#primary_email_select_label). +``` + Now that you have Git installed, I recommend you read up a bit on the basics of it first and get acquainted with whatever git client you're working with, whether its just command-line (Git Bash) or anything else. We're going to run through the process of setting up a Git environment for Space Station 14 so that you can **contribute code through pull requests, create your own codebase**, or just **check out the history of the project.** diff --git a/src/en/general-development/setup/server-hosting-tutorial.md b/src/en/general-development/setup/server-hosting-tutorial.md index 6431c1c2..aec91c16 100644 --- a/src/en/general-development/setup/server-hosting-tutorial.md +++ b/src/en/general-development/setup/server-hosting-tutorial.md @@ -28,6 +28,14 @@ The server needs network ports to be forwarded so that people can connect. By de For more information about how to forward your ports, see: [Port Forwarding](../../server-hosting/port-forwarding.md) +After you have port forwarded, you can use [this site](https://www.whatismyip.com/) to retrieve your public IP address. If you have both an IPV4 and IPV6 try both if one fails. + +Give this to your friends and tell them to direct connect to it. If port forwarding was done correctly they should be able to connect. + +```admonish info +If have an IPV6 address (looks kinda like this ``fd11:5ee:bad:c0de::ab3:3d03``) make sure to include square brackets (``[fd11:5ee:bad:c0de::ab3:3d03]``) when in the direct connect menu. +``` + ### Configure Your Server You can configure settings in the server by editing the config file, `server_config.toml`. The config file is TOML which is basically INI ~~except better specified, somewhat more powerful, easier to misuse, and more annoyingly opinionated (comments NEED their own line)~~. diff --git a/src/en/robust-toolbox/toolshed.md b/src/en/robust-toolbox/toolshed.md index c3e7ac55..e0f218c5 100644 --- a/src/en/robust-toolbox/toolshed.md +++ b/src/en/robust-toolbox/toolshed.md @@ -5,7 +5,7 @@ Toolshed is one of the three primary built-in debug tools (alongside `scsi` and View Variables.) for RobustToolbox, functioning as the game's development console. To use Toolshed, open the debug console or use the debug console in `devwindow`. ```admonish warning -Toolshed is not yet available on the client, so you need to use the `>` prefix command on the client in order to run its commands server-side. +Toolshed is not yet available on the client, so you need to use the `>` prefix command on the client in order to run its commands server-side. Ommiting this will often result in an error stating that you lack permission to run the command even if this is not the case. ``` Toolshed is a **pipeline shell**, and the primary method of performing complex actions is composition of commands. You can simply write multiple commands one after the other and as long as they are compatible, they will have their inputs successively fed to one another. For example, take the following **command run**: @@ -14,7 +14,7 @@ Toolshed is a **pipeline shell**, and the primary method of performing complex a entities with Item count ``` -This is three commands, `entities`, `with`, and `count`. They together form a **command run**, a set of successive commands. You can use the `explain` command to provide information about a command run's flow. It's highly recommended you `explain` command runs you don't understand to get an idea of their flow. +This is three commands, `entities`, `with`, and `count`. They together form a **command run**, a set of successive commands. You can use the `explain` command to provide information about a command run's flow. It's highly recommended you `explain` command runs you don't understand to get an idea of their flow. Note that unlike other pipeline based shells, toolshed's pipeing is *implicit*; you do not need to include a special pipe symbol for commands to be joined into a pipeline. Simply writing them one after another is enough. ``` {{#include toolshed/explain_example_1.txt}} @@ -32,3 +32,9 @@ Toolshed also supports variables in which you can store values. You can use the ``` {{#include toolshed/explain_example_3.txt}} ``` + +```admonish note +Toolshed often spits out lengthy stacktraces upon a command being used incorrectly. Typically, there is a more clear error above the stacktrace in your console. +``` + +For examples of how to string toolshead commands together see [toolshead examples](./toolshed/toolshed-examples.md) diff --git a/src/en/robust-toolbox/toolshed/toolshed-examples.md b/src/en/robust-toolbox/toolshed/toolshed-examples.md new file mode 100644 index 00000000..cc673546 --- /dev/null +++ b/src/en/robust-toolbox/toolshed/toolshed-examples.md @@ -0,0 +1,192 @@ +# Toolshed Examples + +This guide covers some basic examples of Toolshed commands. + +## Interacting with entities + +Most of the time that you are interacting with toolshead you are manipulating entities in some way. + +### Basics +`ent` is a toolshed command that allows us to return an entity with the provided ENTID. By pipeing the output of the command, we can use it to various things on the entity. Some examples include: + +``` +> ent 12345 delete +``` +Will delete the provided entity. + +``` +> ent 12345 replace PlushieBee +``` +Will repalce the entity with the provided prototype, for example, turn it into a bee plushie. + +``` +> ent 12345 comp:ensure Mindshield comp:rm Electrified comp:rm Airtight +``` +Will check if the entity has the "Mindshield" component and add it if needed, then remove the Electrified and Airtight components. + +### Targeting yourself + +`self` will always return the entity currently controlled by you. + +``` +> self rejuvenate / Will heal your character +``` + +### Entity Queries and Filters + +`entities` and `nearby` will return either all entities that exist on the server or entities within a provided tile radius of the input entity. Keep in mind that these require the QUERY permission. + +``` +> entities +``` +Will return a list of all entities on the server. + +``` +> self nearby 20 +``` +Will return all entities in the 20 tile radius of your character. + +``` +> ent 12345 nearby 3 +``` +Will return all entities in the 3 tile radius of entity 12345. + +``` +> entities with ZombifyOnDeath visualize +``` +Will open an UI with all of the infected people on the station, from which you can either VV or TP to them. + +``` +> self nearby 20 replace PlushieBee +``` +Will replace every entity in a 20 tile radius with the provided prototype (in this case `PlushieBee`). + +``` +> entities prototyped CableApcExtension delete +``` +Will delete all LV power cables on the server. + +The most important commands for filtering the output are as follows: + +``` +named "STRING" +``` +Takes in a list of entities and will filter entities based on their name, this command is compatible with the wildcard `.*`. + +``` +> entities named ".*cable" +``` +Will return all entities that end their name with the string "cable". + +``` +> entities named ".*power.*" +``` +Will return all entities that contain the string "power" in their name. + +``` +with [component] +``` +Takes a list of entities and only returns entities that have the specified component. + +``` +> entities with MobState +``` +Will return all mobs on the server. + +``` +actor:controlled +``` +Takes in a list of entities and will return all entities that are currently controlled by a player. + +``` +> entities actor:controlled tp:to self +``` +`self` can also be used as an argument - this will teleport all players to your location. + +``` +select [N] +``` +Takes in a list of entities and will randomly select n entities from the input. + +``` +select [N%] +``` +Takes in a list of entities and will select a percentage of the input. + +Combining filters together we can do as follows: +``` +> entities actor:controlled select 5 tp:to self +``` +Will teleport 5 randomly selected players to the entity you are currently controlling. + +## Fun commands + +### THE BEES WILL CONTINUE UNTIL MORALE IMPROVES: +``` +> self rep 10 spawn:on "MobAngryBee" nearby 10 prototyped MobAngryBee select 1 tag:add "DoorBumpOpener" do "makeghostrole $ID \"Queen Bee\" \"Lead the bees!\"" do "rename $ID \"Queen Bee\"" nearby 10 protoyped MobAngryBee not with GhostRole do "makeghostrole $ID \"Angry Bee\" \"You are an angry bee and you want some pizza.\"" +``` +This command can be split into multiple parts for easier understanding: + +- We start off by getting our current character with `self`. +- Then for that character we execute the command `spawn:on` 10 times: `rep 10 spawn:on "MobAngryBee"`. + - The `rep 10` part repeats the command ten times, and the `spawn:on` command will spawn a provided prototype MobAngryBee on the provided entity - here that's self. +- Then we want to fetch everything in a ten tile radius and filter off the bees we spawned with `nearby 10 prototyped MobAngryBee`. +- Once we have all of our bees, we select one of them using `select 1` and add the tag `DoorBumpOpener` using the command `tag:add`. + - Tags are like components that contain no data, `DoorBumpOpener` allows for opening airlocks by walking into them, just like a player would. +- Next, for the same one bee, we execute the legacy command `makeghostrole` - the first argument is the ID, the second one is the name, the third one is the description. It's important to use the \ symbol before the quotation mark to ensure it is escaped properly. +- Finally, we rename our bee to "Queen Bee". +- Then we fetch all nine other bees and also turn them into ghost roles, just like we did with the Queen Bee. + +Now, a way more efficient way to do this would be to have two separate commands, one for the Queen Bee and one for the Angry Bees. This is just a demo of how complex toolshed can get. + +### GHOSTULARITY: +``` +> entities with Singularity comp:ensure MobState comp:ensure MovementIgnoreGravity comp:ensure InputMover comp:ensure MobMover do "makeghostrole $ID \"Singularity\" \"FUCK\"" +``` + +This command will turn all singulos on the server into player controlled ghost roles. + +### Bee plushie grenade + +Have you ever wanted a bee plushie grenade? You can have one with this simple command! +``` +> self spawn:on "GrenadeStinger" do "rename $ID \"bee plushie grenade\"" do "vvwrite /entity/$ID/ClusterGrenade/FillPrototype \"PlushieBee\"" + +``` +You can replace the `FillPrototype` of cluster grenades with any valid Prototype. Keep in mind that any explosives you spawn this way will be activated by default, so you might not want to use it to spawn thirty Holy Hand Grenades. + +### Put the station into debt + +Salvage keeps powergaming? Put the station in debt with this one simple solution! +``` +> stations:get do "vvwrite /entity/$ID/StationBankAccount/Balance 1000" +``` +Make sure to replace the 1000 with the balance you want to set. + +Alternatively, you could go into F7 > Objects > Stations, check the stations ENTID and then do: +``` +vv /entity/ENTID/StationBankAccount +``` + +## Scripts and You + +Scripts can be used to automate certain tasks or commands. To create a new script, you will need to create a new file in your Space Station 14 [client data directory](../user-data-directory.md#Client). + +The file name should be whatever you want the script to be called. You can edit it with any text editor, just make sure to save it as a file with no extension. + +Admins will often have a script to customize their ghosts. Here is an example of one: + +``` +> self not prototyped AdminObserver do "aghost" +> self comp:ensure ShowCriminalRecordIcons comp:ensure ShowJobIcons comp:ensure ShowMindShieldIcons comp:ensure ShowSyndicateIcons comp:ensure Grammar comp:ensure Identity +> self do "vvwrite entity/$ID/Ghost/color '#00D2AD'" +> self do "vvwrite entity/$ID/Description \"GHOST GANG!!\"" +> self do "vvwrite entity/$ID/Grammar/Attributes[gender] Male" +``` + +- The first line makes sure you are an admin observer. +- Next, we make sure to add any of the components that are helpful for admining if needed. These show up the job icons, antag icons, mindshields. The `Grammar` and `Identity` components are used later for customizing the aghost. +- The third and fourth line set the ghost color and description using `vvwrite` with a path and a value. +- The last line changes the pronouns to show up as He whenever someone inspects the ghost. + +When you want to run the script in game, all you have to do is use the exec command. If you called the above script "admin", you would run the command `exec /admin`. diff --git a/src/en/server-hosting/setting-up-ss14-watchdog.md b/src/en/server-hosting/setting-up-ss14-watchdog.md index 10fa664f..b2176c96 100644 --- a/src/en/server-hosting/setting-up-ss14-watchdog.md +++ b/src/en/server-hosting/setting-up-ss14-watchdog.md @@ -57,6 +57,8 @@ Assuming you've followed the structure laid out above, you simply need to have a ## Watchdog Configuration +Watchdog's config file is ``appsettings.yml`` + The watchdog configuration is split into two major sections: + Global elements, shared across all instances (servers). diff --git a/src/en/space-station-14/core-tech/entity-tables.md b/src/en/space-station-14/core-tech/entity-tables.md new file mode 100644 index 00000000..a458e87e --- /dev/null +++ b/src/en/space-station-14/core-tech/entity-tables.md @@ -0,0 +1,202 @@ +# Entity Tables + +**Entity tables** are a powerful way of defining entities for container fills and spawners. +The system is made up of recursive sets of selectors, each of which can define custom behavior for choosing entities. + +## Usage + +You can get the spawns from a table using `EntityTableSystem.GetSpawns`. +This function call only takes in an `EntityTableSelector` with an optional param for `System.Random`, allowing for deterministic applications. + +As of the writing of this guide, EntityTables are primarily supported by two components, `EntityTableContainerFillComponent` and `EntityTableSpawnerComponent`. + +`EntityTableContainerFillComponent` serves as a direct replacement for `ContainerFillComponent`. +It uses the same general syntax besides swapping out the list of `EntitySpawnEntry`s for a `EntityTableSelector`. + +Similarly, `EntityTableSpawnerComponent` is a replacement for `RandomSpawnerComponent`. +However, they do not share the same variables. +This version only supports a table and an offset, and not the separate lists and chance variable of the old system. +The same effect can be achieved through the use of nested `GroupSelectors` with an overall `prob` definition and `weights` corresponding to the previous chances. + +### Example Syntax + +```admonish warning "Type Specification" +When writing EntityTables, you must use the `!type:[Class Name]` syntax when you specify a selector. + +The one exception is `EntSelector`. +Simply specifying the ID will cause the linter to assume the specified selector is an EntitySelector. +This greatly reduces the yaml for large tables. +``` + +Here is a reusable entity table prototype: +```yaml +- type: entityTable + id: LockFillTable + table: !type:AllSelector # <-- This means that all the children will be selected + children: + - id: ClothingMaskBreath # <-- This is just a single instance of an entity + - !type:GroupSelector # <-- This means that only one of the children will be selected + children: + - id: EmergencyOxygenTankFilled # <-- All selectors have a default weight of 1 + - id: OxygenTankFilled + weight: 2 # <-- This means this entry is twice as likely to be selected + - id: ToolboxEmergencyFilled + prob: 0.5 # <-- This means there is a 50% chance that this selector will be used. +``` + +Here's an example of one in-lined into an entity prototype: +```yaml +- type: entity + id: ClosetFilled + components: + - type: EntityTableContainerFill + containers: + entity_storage: !type:AllSelector + children: + - !type:NestedSelector # <-- This will recursively call GetSpawns on an EntityTablePrototype + tableId: LockFillTable + - id: ClothingMaskGas + amount: !type:ConstantNumberSelector # <-- This will select exactly 3 of the specified entity + value: 3 + - id: StrangePill + amount: !type:RangeNumberSelector # <-- This will select between 2 to 6 (inclusive on both sides) of the specified entity + range: 2, 6 +``` + +## EntityTableSelectors + +### Common Variables + +All EntityTableSelectors have the following variables: + +- **Rolls:** The number of times a given selector is run. +`Prob` chances will be run for every roll +- **Weight:** A weight used to determine which selector is chosen for `GroupSelector` +- **Prob:** Simple probability used to determine if a selector is ran. +Goes from 0 to 1 + +### EntSelector + +- **Id:** The ID of the EntityPrototype you want to select. +Required. +- **Amount:** A `NumberSelector` corresponding to how many of `Id` do you want to select. +Defaults to 1 if nothing is specified. + +EX: +```yml +root: +- id: PlushieLizard + amount: !type:ConstantNumberSelector + value: 5 + +# or + +root: !type:EntSelector +- id: PlushieLizard + amount: !type:ConstantNumberSelector + value: 5 +``` + +### NoneSelector + +Returns nothing. +This can be used in conjunction with `GroupSelector` for probability. + +EX: +```yml +containers: +- storage: !type:NoneSelector +``` + +### AllSelector + +`AllSelector` allows for basic control in choosing a list of selectors that you want to use in conjunction with each other. + +- **Children:** A list of other EntityTableSelectors that will be selected from. + +EX: +```yml +root: !type:AllSelector + children: + - id: PlushieLizard + - id: ClothingMaskGas +``` + +### GroupSelector + +`GroupSelector` serves as a replacement for EntitySpawnEntry's OrGroup. +Since only one of the children is chosen, a common usage is nesting multiple GroupSelector's within each other to adjust the chance of an item being picked without explicitly calculating Weights. + +Similarly, an EntityTable with a GroupSelector as the root can be used as a generic pool. +This makes picking multiple items from the pool as simple as increasing the value of `Rolls`. + +- **Children:** A list of other EntityTableSelectors, one of which will be chosen and selected from based on chance and the selector's `Weight` value + +EX: +```yml +root: !type:GroupSelector + children: + - id: PlushieNar + - id: PlushieRatvar +``` + +### NestedSelector + +`NestedSelector` exists primarily to reduce duplication of yaml. +Since a table (or part of a table) can be specified as a prototype, using this allows you to reference it multiple times in many places. + +- **TableId:** The string ID of a EntityTableSelector. + +EX: +```yml +- type: entityTable + id: test + table: !type:GroupSelector + children: + - id: PlushieLizard + - id: PlushieNar + - id: PlushieRatvar + +- type: entity + id: PlushSpawner + components: + - type: EntityTableSpawner + table: !type:NestedSelector + tableId: test +``` + +## ValueSelectors + +### NumberSelectors + +`NumberSelector` is just a generic way of specifying a numerical value for various selectors. + +#### ConstantNumberSelector + +- **Value:** Returns the specified value. + +EX: +```yml +amount: !type:ConstantNumberSelector + value: 4 +``` + +#### RangeNumberSelector + +- **Range:** Returns a value within the specified range (inclusive on both sides) + +EX: +```yml +rolls: !type:RangeNumberSelector + range: 6, 2019 +``` + +## Custom Selectors + +To implement a custom entity table selector, create a new class that inherits from `EntityTableSelector`. +Then, simply override `GetSpawns(System.Random, IEntityManager, IPrototypeManager)` and create your implementation. + +You can add any datafields on the class but you cannot use dependency injection to add systems. +If you want to call a Manager or System, the easiest way to do it is to create a new `EntitySystem` that has a public API that handles the selection, then get the system via the supplied `IEntityManager`. + +NumberSelectors work the same, simply using `NumberSelector` instead of `EntityTableSelector`. \ No newline at end of file diff --git a/src/en/space-station-14/mapping/guides/general-guide.md b/src/en/space-station-14/mapping/guides/general-guide.md index c97537b5..73d0dcce 100644 --- a/src/en/space-station-14/mapping/guides/general-guide.md +++ b/src/en/space-station-14/mapping/guides/general-guide.md @@ -83,7 +83,7 @@ Now to start creating maps follow the below steps: * If you want to test the lighting on your map without leaving the editor, use the "mapinit" command. Do **save before doing this** as it will ruin your map if you save after running this command. * Use https://affectedarc07.github.io/SS13WebMap/ to see most SS13 maps online - (https://game.ss13.moe/minimaps/images/maps/ for the /vg/ ones) -* While testing your map, you might not want to be bothered to set up power each time. In that case, try: `forall with Battery do setbatterypercent $ID 100` +* While testing your map, you might not want to be bothered to set up power each time. In that case, try: `> entities with Battery do "setbatterypercent $ID 100"` * Map auto-saving is enabled by default and goes to the server data directory every 10 minutes (cvar `mapping.autosave_interval`). You can turn it off with `toggleautosave [map id]` or change the `mapping.autosave` cvar. ## Mapping Actions diff --git a/src/en/space-station-14/round-flow/proposals/changeling.md b/src/en/space-station-14/round-flow/proposals/changeling.md new file mode 100644 index 00000000..f7bea079 --- /dev/null +++ b/src/en/space-station-14/round-flow/proposals/changeling.md @@ -0,0 +1,316 @@ +# Changeling antagonist + +| Designers | Implemented | GitHub Links | +|----------------------|-------------|--------------| +| alzore_ (Discord) | :x: No | TBD | + +## Overview +A rare space creature with absolute control over its biology, mind over the flesh, or something like that. The changeling is the apex predator of all sentient life, feeding on their genomes and biomass to sustain its ever-shifting body. The station is the changeling's hunting ground, and the crew is its prey. It acts as a lone hunter, it doesn't collaborate with anyone, even other changelings, and it wouldn't hesitate to kill and feast on its own kind. +The changeling is a roundstart opt-in role like traitor, it starts disguised as the player's regular character with the assumption that while off-station the changeling quietly captured and devoured them, posing as them to get onto the station to further its survival. Changelings always have a single objective. **survive** and make it to centcom. Its restraint status is irrelevant, it just needs to be alive. + +The goal of this version of the changeling is to create a terrifying roundstart antagonist, taking advantage of body horror elements to assimilate the crew into itself. The changeling will regularly round remove people to sustain its murder spree, and its own failure will round remove it as a result. + +## BIOMASS +The changeling begins the round with around 150 biomass, this biomass depletes by 1 every 12 seconds or so. Biomass is a changeling's way of sustaining its body and abilities, without enough biomass, a changeling will wither and die. The only way to increase the amount of biomass a changeling has is to consume bodies. Consuming one person will grant the changeling 100 biomass, this means a changeling can survive for 20 minutes without using abilities for every person it devours. Rotting corpses cannot be devoured for biomass, and bloated corpses cannot be devoured for DNA. + +A single changeling without the use of eyeslugs should round-remove somewhere around 4 people purely to survive, even more if it uses abilities. A loud changeling that doesn't die might eat a quarter of the crew by the time the shuttle docks at centcomm. + +### HUNGER +A changeling will always be able to see its biomass count in place of its hunger status on the right side of the screen, and as this number lowers various negative effects occur such as... +- At 50 biomass, only popups visible to the changeling will occur. + +- at 25 biomass, outwardly visible symptoms but not dead giveaways will occur. + +- at 10 biomass or lower, there will be semi-dead giveaways that the changeling is a changeling, things like vomiting up blood or spasms. These can also be symptoms of deadly diseases or the eyeslug. + +- Once the changeling reaches 0 biomass, it falls to the ground and shows a big bold popup visible to everyone in the area, then turns into its true form after around 10 seconds. + +- A changeling with 0 or less biomass is considered "Starving" and cannot use recovery or transformation abilities, it takes constant damage that scales depending on how far into the negatives its biomass is. + +- If a starving changeling dies for any reason, it turns into dust after around 5 seconds. + +## ABILITIES +The changeling starts with a few free abilities and can unlock more at the cost of biomass. + +**NAME | UNLOCK COST | USE COST | NEEDED FORM** + +#### FREE ABILITIES +The changeling, in its weakest state, is still able to do some pretty nasty stuff. These abilities are central to the changeling's functionality and it can never not have them. + + +- **Transform | free | low | disguised** + +Opens a radial menu displaying all the people the changeling has devoured including the person it started the shift as, selecting one will display a small red popup to anyone nearby and begin a 5-second doafter. Once this concludes, the changeling will change its outward appearance and vocal cords to that of the selected victim. The trademark ability of the changeling. + +Intended to allow the changeling to hide among the crew and easily infiltrate departments. + + +- **Devour | free | free | any** + +The changeling produces a loud and obvious sound, displays a big bold popup to anyone nearby, and after a 2-second windup, begins to deal rapid brute damage to a humanoid, the damage is capped at 350 of each type. If either the changeling or the humanoid moves, the damage stops. After 10 seconds of damage, the humanoid will be transformed into a husk devoid of any organs. This ability shreds any jumpsuit the body was wearing, all other clothing remains on the husk until removed. This ability cannot be used if the person is wearing an outerclothing piece with more than 10% resistance to any brute damage. +If the changeling devours another changeling, it will gain all of the enemy changeling's biomass in addition to triple the normal amount it would gain, as well as all of the dead changeling's unlocked abilities and DNA. + +Intended to give the changeling a method of obtaining biomass while causing significant irreparable damage to the crew in the process and solidifying it as entirely *against* the crew. + + +- **Stasis | free | low | any** + +The changeling enters a fake dead state and slowly recovers its wounds to eventually revive itself. If a changeling is rendered dead, it can activate this ability at any time to recover. A changeling's corpse in stasis will never rot, but it will display freshness amounts to the crew up to nearly rotting. + +Intended as a backup option for a changeling that is wounded from combat and can't go to med, or for a changeling the crew simply didn't take the time to dispose of to have another chance. + + +- **Shed | free | free | disguised** + +The changeling initiates a 5-second doafter and displays a big bold popup visible to anyone nearby. Once the doafter concludes, the changeling enters its true form, dropping any clothing it was wearing except for its ID slot, which will be stored inside itself and not be outwardly visible, and the item in its right hand. + +Intended as a way for changelings to have a distinct combat form that alerts everyone instantly and triggers fight or flight responses in the crew. + + +- **Mask | free | high | true** + +Replaces Shed while in true form. The changeling turns back into a normal humanoid using one of the DNAs it has access to. It will drop anything it had in its ID slot upon doing this, as it will not be wearing a jumpsuit. + +Intended as a way for changelings to hide amongst the crew after having either won a one-on-one fight or having succeeded in a massacre and wishing to remain hidden in the aftermath. + + +## HIVEMIND +The changeling can choose to integrate minds into itself instead of simply devouring them. This is useful for retaining personalities or quickly allowing minions to be controlled. All beings including the changeling that are within a hivemind can speak to each other using :h. Absorbed minds are forced to follow any orders given by the changeling, and griefing the changeling would be extremely rule-breaking. + + +- **Hivemind | medium | free | any** + +Using this ability will show a radial menu which allows the changeling to use any of the abilities listed under this HIVEMIND section. Once hivemind is unlocked, all hivemind abilities are unlocked and do not need to be purchased separately. + +Intended as a way to keep a changeling's victims in the round, losing against a changeling remains enjoyable. + + +- **Relinquish** | free | free | disguised** + +Opens a radial menu displaying all minds currently in the changeling's hivemind, upon selecting one, that mind will be granted control over the changeling's body. + +Intended as a way for a changeling to disguise as someone while not drastically changing personalities, a changeling would give up control to the person they are pretending to be while giving them commands through the hivemind channel. + + +- **Restrict** | free | free | disguised** + +Toggles whether minds can use a changeling's abilities while in control of the changeling's body. + +Intended as a way to prevent salty players from causing too much damage to a changeling if they choose to grief. + + +- **Retake** | free | free | disguised** + +Instantly retakes control from a mind that has been granted control. + +Intended as a way for the changeling to remain as the master of its own body. This is instant in case a mind decides to grief, a changeling can act quickly to undo whatever the mind did. + + +- **Purge** | free | free | disguised** + +The changeling erases an absorbed mind from itself, kicking it out into the afterlife. + +Intended as a way to remove players who are bitter, incompetent, or malicious to the changeling from the hivemind channel. + + +- **Emancipation | medium | free | any** + +Opens a radial menu allowing the changeling to select a mind that will instantly inhabit the next minion spawned. Using this ability again before a minion is spawned will cancel it. If a minion dies while under the control of a mind from the hivemind, the mind will be returned to the changeling with full knowledge of the events that occurred. + +Intended as a way to quickly summon minions and reward players for remaining in a changeling's hivemind, also gives players who died to a loud changeling something to look forward to. + + +#### STEALTH +The changeling in a disguised state shouldn't be entirely under the radar. The crew would know there is SOMETHING among them, picking them off, hunting. The changeling's stealth abilities should allow it to remain out of sight while killing, and allow it to deceive the crew and make them feel safe, or throw them off the trail. + +- **Mimic | medium | low | disguised** + +Instantly opens the voice mask UI, allowing the changeling to modify its voice once. Using this ability again will revert the changeling's voice to the disguise currently in use. + +Intended as a way for the changeling to seed distrust, or manipulate people into actions that are favorable to it. + + +- **Chameleon | medium | low | disguised** + +Creates fleshy clothing in the jumpsuit, shoes, head, glasses, mask, gloves, and backpack slot. This clothing can be modified just like chameleon clothing by any changeling wearing it. Cutting this clothing will yield fleshy strips rather than cloth, and if a moth eats it they will immediately know its true nature. If the changeling is already wearing something in any of those slots, no clothing will be made and the biomass cost will be reduced by 1 for each clothing not made. + +Intended as a way for the changeling to entirely change its disguise on the fly, while not being easily metagameable like tg flesh clothing is. + + +- **Lesser | medium | medium | any** + +The changeling shrinks into a monkey or kobold, retaining any clothing that a monkey can wear and dropping anything else as well as freeing itself from cuffs. In this form, the changeling can ventcrawl but is only able to use the stasis, shed, transform, and stinger abilities. + +Intended as a way for a changeling to appear inconspicuous to an angry crew, or to escape a bad situation without fighting. + + +- **Imprint | low | low | disguised** + +Opens a radial menu displaying all the people the changeling has devoured including the person it started the shift as. Selecting one will instantly and silently change the changeling's fingerprints to that DNA. Fingerprints are retained regardless of disguise. + +Intended as a way for a changeling to hide its tracks and throw people off the trail, while also leaving a chance for mistakes if a changeling never changes its prints after using the ability once. + + +- **Mindshield | medium | low | disguised** + +The changeling instantly begins to appear mindshielded to anyone wearing a sechud. Using this ability again toggles the mindshield. + +Intended as a barrier for entry to infiltrating security/command. A changeling can always get a real mindshield, but then they wouldn't be able to easily disguise as a passenger or scientist when security comes knocking. + + +#### STINGERS +The changeling's stinger can inject its prey with various chemicals to weaken or confuse them, with a mixture of effective stealth and combat uses. Other changelings are immune to these chemicals. + + +- **Stinger | low | low | disguised** + +Transforms its currently active arm into a disguised stinger that cannot hold items. This stinger is not visible on examination, sprites, or in strip menus. Using the stinger inhand with Z opens a radial menu showing all chemicals the changeling has unlocked. Clicking on someone with the stinger inhand will inject them with 20u of the selected chemical. + +Intended as a way for a changeling to stealthily administer chemicals to victims, possibly injecting people with toxins in medbay, or pricking their target before they can realize what's going on. + +- **Tailsting | low | medium | any** + +The changeling grows a large tail with a sharp stinger at the end, giving them a third hand slot with the stinger as an item. The stinger is a weapon, dealing 8 pierce and 2 slash on hit with a 2-second cooldown between hits. Using the stinger inhand with Z opens a radial menu showing all chemicals the changeling has unlocked. Hitting someone with the stinger will inject them with 40u of the selected chemical at the same biomass cost as the chemical would normally be, this means the chemical will last for twice as long as usual. Someone hit with this stinger will receive a big bold popup that they have been stung by a changeling if it wasn't already obvious. + +Intended as a way for a changeling to use its stingers combatively, or to inject a lone target with a more potent dose of chemicals for an easier time subduing them. + + +- **Gibberizol | low | low | stinger** + +A chemical that turns all speech of its victim into garbled nonsense for 100 seconds, but does not entirely prevent them from talking. + +Intended to be a cheaper option when taking down lone targets, or for causing confusion in a hectic scenario. Victims can still cry out over the radio and people can recognize the garbled text as being from a changeling, but nobody will know where the person is without suit coordinates or other info. + + +- **Mute-agen | low | medium | stinger** + +A chemical that prevents targets from talking at all for 40 seconds. The target will feel a painful sting when this chemical is injected. + +Intended as a more risky, expensive option for taking down lone targets or causing difficulty in communication in a hectic scenario. Victims can fight back more plausibly as they will instantly be made aware they are under attack by a changeling, but they cannot alert the rest of the station easily. + + +- **Impedrezol | medium | medium | stinger** + +A chemical that slows targets down by 20% for 20 seconds. This does not stun or freeze the target. + +Intended to be combined with Mute-agen or Gibberizol for an easier time subduing targets, or used in combat to drastically weaken a particular foe. + + +- **Hallucinol | medium | medium | stinger** + +A chemical that will give a target the trip of their life, slow their movement by 10%, and entirely prevent them from metabolizing any other chemical for 20 seconds. + +Intended to cause a lot of confusion in people, and the people around them. Would cause hallucinations which may throw off someone's game in combat, and preventing chemicals from metabolizing might stop someone high on stimulants or omnizine from rushing the changeling easily. + + +- **Chitizene | medium | high | stinger** + +A chemical that slowly morphs the target's arm into a dull changeling armblade that does 5 slash and 5 blunt damage for 8 minutes. The process takes 10 seconds, and the target will be aware of the transformation 5 seconds before it occurs. + +Intended to cause a lot of confusion, chaos, and to frame someone who is not the changeling. Also has uses with preventing gun wielding, since the armblade takes up one of the target's hands in combat. + + +- **Licoxide | high | high | stinger** + +The target is injected with a chemical that causes them to be randomly shocked and stunned for 20 seconds. The target will feel a painful sting when this chemical is injected. + +Intended as a very potent offensive chemical, the high price makes it unviable for a stealthy changeling to cause general chaos with. Takes someone out of the fight without entirely preventing them from fleeing for the entire 40-second duration assuming the changeling used the tail stinger. + + +#### MINIONS +The changeling can create all sorts of horrors from its ever-shifting mass of biological matter. These generally take the form of detached body parts. All of the changeling's minions except for the headcrab are ghost roles with a short raffle. Ghost role minions cannot verbally speak, but can silently communicate with the changeling that created it as if it were wearing a headset. The headcrab can speak to people. + +- **Eyeslug | high | low | any** + +Starts a ghost role raffle that lasts for 10 seconds, once it concludes one of the changeling's eyes will fall out as an eyeslug with the winning ghost in control. The eye will regrow instantly. + +Eyeslugs have 5 HP and move slower than a human. They can ventcrawl, move underneath doors, and are small (1x2) items that can be picked up. An eyeslug can interact with a stunned/critical humanoid to begin a 1-second doafter which will be cancelled if either move. Once concluded, the eyeslug will burrow into the victim's face and infect them with a disease. Infecting a humanoid kills the eyeslug. + +The disease given by eyeslugs will cause the humanoid to begin exhibiting outwardly visible symptoms identical to that of a hungry changeling, starting symptoms at 35 biomass, and progressing at half the rate a regular changeling would progress at. After 14 minutes of infection, the victim will begin taking slow damage, and the changeling will be made aware through their hivemind channel. The longer a victim is infected, the more biomass a changeling will gain from devouring them, but a dead victim will not progress their infection, and a rotting victim will immediately lose all bonus biomass and be cured. I do not currently know how an infection would be cured normally since we don't have surgery. +- At 5 minutes infected, biomass will increase to 150 +- at 10 minutes infected, biomass will increase to 250 +- at 15 minutes infected, biomass will increase to 450, biomass does not increase past this point. + +Intended as a method for a more careful and calculated changeling to efficiently collect biomass without causing too much damage to the crew, which would attract a lot of attention to itself. Could also be used as scouts, or used to cause chaos by infecting random people and having them require medical to cure them. A person could also be infected, know they are infected, and fear the changeling's oncoming attack, driving up the terror already instilled. + + +- **Handspider | low | medium | any** + +Starts a ghost role raffle that lasts for 10 seconds, once it concludes one of the changeling's hands will fall off as a handspider with the winning ghost in control. The hand will regrow instantly. + +Handspiders have 15 HP and move slower than a human. They have the ability to leap at people to stun them for 3 seconds if they connect, but cannot deal damage. The handspider cannot stun someone wearing a mask unless that mask is cosmetic, such as the clown mask, and The handspider will be stuck in place on top of their target for 2 seconds after a successful stun. A handspider can grasp a single item to rotate and operate it, but it cannot move while doing so. If someone picks up the item the handspider will be thrown off. + +Intended as a scout, or a partner for an eyeslug. A handspider could stun a victim while the eyeslug infects them, or it could simply assist the changeling in combat by stunning poor souls that dared to fight. + + +- **Legworm | medium | high | disguised** + +Starts a ghost role raffle that lasts for 10 seconds, once it concludes one of the changeling's legs will fall off as a legworm with the winning ghost in control. The changeling's missing leg will regrow after 15 seconds, and during that time they are unable to move. + +Legworms have 50 HP and move noticeably slower than a human. They deal 16 blunt damage on M1 and can disarm on M2. Legworms heal 12 brute and 1 heat damage for every hit they land, that's only 4 of each brute damage type. + +Intended to either cause chaos and distraction while the changeling discreetly acts elsewhere or to assist the changeling in major fights. + + +- **Chitinworm | medium | high | true** + +Replaces the legworm ability when in true form, and does not require a separate purchase. +Starts a ghost role raffle that lasts for 10 seconds, once it concludes one of the changeling's legs will fall off as a chitinworm with the winning ghost in control. The changeling's missing leg will regrow after 15 seconds, and during that time they are slowed by 25%. + +Chitinworms have 30 HP and move noticeably slower than a human. They deal 9 blunt and 9 slash damage on M1 and wideswing on M2. + +Intended to be a high-cost method of turning the tides of a fight, the changeling can create multiple of these during a single encounter if it has the biomass to do so. + + +- **Headcrab | medium | free | any** + +A changeling begins a 20-second invisible doafter that triggers red popups every 4 seconds for its duration. Once completed, the changeling's neck breaks and its head leaps off in the direction of the changeling's cursor. + +The headcrab has 20 HP and moves at the same speed as a human. It can ventcrawl and deals 10 slash damage on M1. It has the ability to leap at people to stun them for 5 seconds if it connects regardless of mask status, it will not be stuck in place after a successful stun. A headcrab can burrow into a dead/critical person after a 5-second doafter, and five minutes after burrowing the changeling will take control of that person. The changeling will have 50 biomass and no abilities after taking control of a person but still has access to all its DNA and hivemind. If the headcrab burrows into a changeling in stasis, it will be destroyed. The changeling that destroyed it will receive 30 biomass and all the regular benefits of devouring another changeling, except for its abilities since the headcrab has none. +If a headcrab dies the changeling is fully dead, regardless of if its body is still intact. A dead headcrab can be picked up and is a medium item. Grinding it nets you 40u of chitizene, and selling it to cargo is worth 25,000 spesos. + +Intended as a last resort for a discovered changeling that's about to be gibbed/cremated but either cannot use rejuvenate or doesn't want to. + + +#### COMBAT +Combat abilities are mostly only available to a changeling in its true form, with the exception of the arm blade as a method of fighting while still in disguise. + +- **Armblade | medium | medium | disguised** + +The changeling displays a big bold popup to anyone nearby and begins a 5-second doafter during which it is slowed by 50%. Once this concludes, the changeling's currently active arm will be replaced by an armblade. The armblade swings once a second, dealing 30 slash damage. Using this ability again triggers another popup and doafter, removing the armblade. + +Intended as a combat option in the disguised state for subduing victims or being caught off-guard. + + +- **Rejuvinate | medium | 5/point of damage | true** + +The changeling displays a big bold popup to anyone nearby and begins a 4-second doafter. Once this concludes, the changeling will heal **ALL** damage dealt to it. If the changeling is critical or dead in its disguised form, it performs a 10-second invisible doafter with no popup, after which it will instantly enter its true form at full HP with the usual big bold popup and loud sound effect. If the changeling does not have enough biomass to use this ability, it will use biomass until it reaches -50, and if that is still not enough to revive it from a critical state, it will dramatically explode into a pile of gibs. + +Intended as a last resort for a loud changeling that has been utterly cornered and is about to be gibbed/cremated, or for an **extremely** successful changeling to become a one-man army by expending all their biomass in a single fight against the armed sec/cargo team. + + +- **Shriek | high | medium | true** + +The changeling screeches loudly, causing any non-changeling in a 7-tile radius (blocked by walls) to instantly take 50 stamina damage. + +Intended to aid the changeling in a pursuit, or give it a way to combat multiple foes. + + +- **Immunity | medium | high | true** + +The changeling doubles its passive biomass consumption to become entirely immune to poison, radiation, and cellular damage. Does not remove already existing damage. + +Intended as a method of fighting attacks such as foam bombs, hyposprays, and radioactive artifacts. Could also be used for things such as walking past the singularity. Not meant to be used at all times. + + +- **Spacefaring | medium | high | true** + +The changeling loses 20% movement speed and doubles its biomass consumption to become immune to the pressure and cold of space. + +Intended as a way for a loud changeling (a disguised one can just use an EVA suit.) to survive a spacing either brought on by its own actions, random events, or by a desperate crew trying to kill it. Not meant to be used at all times. + + +## REQUIRED CHANGES +- Salvage corpses now spawn very bloated. They cannot be consumed by the changeling for food. +- Add ventcrawling for mice, rats, etc. +- Some implementation of virology for the eyeslug infection and for early starvation symptoms to not be metagamed.