## About The Pull Request
Mafia players are now sent to their last body when the Mafia game ends,
and in the meantime they have text saying why they are dead.
They can still be revived during this period, and when the game is up
they'll be forced back into their body if alive, if they are dead then
they'll just be able to re-enter their corpse as normal.
Also since I was poking around in Mafia stuff:
- I removed mafia observing because it was unused (this previously was
used to allow ghosts to see Changeling chat).
- I fixed it being a Draw when there was one Town or Changeling left.
- I fixed the role list showing some roles multiple times
- I fixed the Chaplain not being able to use their night ability (and
therefore being completely useless)
- I added prevention to prevent Admins from causing runtimes or straight
up crashing the server, with a very real chance it can happen purely by
accident, through the Admin UI.
I'm hoping to change how this actually does the job because I find it to
be very bad coding practices, but my problem is that everyone who signs
up for Mafia is a ghost, and they are added into the game through their
CLIENTS, so we don't have access on the mafia controller or the role, to
the player's previous body or mind, without this shit.
Also adds a new mafia board icon
Made by tatax and I find it fits more the theme of Mafia than the
current one.
New UI
## About The Pull Request
Sets up an auto-wiki run for Soup.
It's all in the in game cookbook, but keeping the wiki up to date is
good.
Still figuring out how auto-wiki works with the help of Smithers, so it
might need to be updated in a follow-up PR.
```
{{Autowiki/SoupRecipeTemplate
|name=Tomato Soup
|taste=tomato
|foodtypes=Vegetables, Fruits
|description=Drinking this feels like being a vampire! A tomato vampire...
|icon=soup/Tomato Soup
|requirements=50 units Water, 2 tomatos, at temperature 450K
|results=30 units Tomato Soup, 20 units Tomato Juice
}}
```
Templates:
https://tgstation13.org/wiki/Template:Autowiki/SoupRecipeTemplatehttps://tgstation13.org/wiki/Template:Autowiki/SoupRecipeTableTemplate
## About The Pull Request

**This PR:**
- Reworks most* existing soup into reagents.
- Adds Stoves and Ranges. Ranges replace most* existing ovens.
- Adds soup pots, to cook soup
**How does it work?**
In the kitchen you will find a stove now.
Stoves act as a "reagent container heater", essentially a chem heater.
You can set a pot onto the stove.
To make soup, visit the cooking recipe book for a guide. Most recipes
are the same as before, just tweaked slightly - Add water to the pot (50
units for 1 batch generally), then add all the corresponding ingredients
to the pot. Set the pot out on the stove and right click it to turn it
on. If the recipe's correct, shortly it will start to mix and give you
soup!
One soup recipe will give you roughly 3 servings of soup. You can pour
our the soup into a bowl using a ladle or just by pouring it manually.
Of note: **All of the reagent contents of the ingredient are transferred
into the soup.** Better, more nutrient rich ingredients produces more
soup, and poisoned produce will pass it on.
If you place the soup into a chem master, you will notice it's roughly
half "soup reagent" and half a variety of reagents, including nutriments
/ proteins. This is your soup! It is recommended you serve your soup
with the reagents included, as they make up more nutrition for the
customer, however you can separate it out if you're picky.
**Todo:**
- [x] Fill out the PR body a bit more
- [x] Mapping (wait for big merge conflict pr to go past)
- [x] Soup colors
- [x] Balance pass over for soup recipes
- [x] TODOs
- [ ] Unit tests
- [x] Cullen Skink's recipe is invalid
- [x] Try to see if there's an easy way to prevent soup from fattening
you up too easy.
## Why it's good for the game
Adds some more depth to the kitchen and moves chef away from the
click-button-get-food style that exists.
Allows for inherently custom soups by the way of making it reagents, so
no need to support custom soup food items.
## Changelog
🆑 Melbert, stove and pot sprites by Kryson, ladle sprite by Kinneb
add: Kitchens are now stocked with Ranges.
add: You can now print (and create) Stoves.
add: The dinnerware vendor now dispenses ladles.
add: Spoons can now actually spoon... things.
add: Soup has been reworked entirely. Soups are now reagents, cooked via
a soup pot on a Stove or Range. Simply add water and your required
items, then apply heat. Be careful not to boil over!
add: Stoves, Ranges, and Griddles will now heat up their surroundings -
don't turn them on around plasma!
fix: Fixes being able to cook in an Oven while the room is depowered
qol: Hitting a customer bot with an incorrect recipe no longer counts as
a hostile attack leading to your demise shortly after
refactor: Customer bots that request a reagent now use custom orders
code: Cut down a lot of code in the crafting menu code, and removes some
ugly ispaths
del: Soup is no longer food items, so can't appear in random food pools
(at least not yet).
balance: Virus Food recipe now requires you cool it to 200k.
/🆑
## About The Pull Request
This sprite file had been a dumping ground for miscellaneous sprites for
the past decade. It's bloated and full of random kinds of icons and even
has a few unused ones. It's time to reorganize them into their own
separate dmi's based on theme.
## Why It's Good For The Game
Better organization and easier access when looking for stuff.
## Changelog
🆑
imageadd: Split all icons in weapons_and_items.dmi to their own
categories
imagedel: Removed some unused icons
/🆑
## About The Pull Request
Refactors regenerate organs to be slightly more intelligent in handling
organ changes and replacements.
Noteably:
- We don't remove organs that were modified by the owner; such as
changing out your heart for a cybernetic
- We early break out of the for loop if they aren't supposed to have an
organ there and remove it
- We check for the organ already being correct, and just healing it and
continuing if it is
Also changes the names of some of the organ helpers into snake_case
### Mapping March
Ckey to receive rewards: N/A
## Why It's Good For The Game
## Changelog
---------
Co-authored-by: Jacquerel <hnevard@gmail.com>
## About The Pull Request
Firstly, this var was on `/mob`, even though only `/mob/living` and
`/mob/dead` could have ever used it, so who knows how much needless
memory it was consuming on stuff such as `oranges_ear` that would never
ever ever use something like this.
Edit: okay instead of memory it just polluted variable edit windows for
all /mob when it didn't need to. I like having a slim VV window
Secondly, it's a technical improvement over the previous system as we
are able to "track" where a suicide originates from, and how we can
track that from mob-to-mob-to-mob. Previously, the boolean `suiciding`
would only inform us if they had ever been connected to a mob that had
ever committed suicide, but now we are able to precisely determine which
mob gave them the trait that they must now apparently bear until the
round restarts.
## Why It's Good For The Game
Less memory usage, more indepth ability to track suicides in case you
really need that dexterity. Currently no implemented code could benefit
from using it, but it would be pretty neat if someone could figure out a
way to have someone be guilt-tripped whenever they look into a mirror
and seeing the reflection of their past life? This PR won't actually
help you code that and it'll probably require a bit more work, but it's
a possibility of some cool interactions you can do when you have this
information available to you.

## Changelog
🆑
refactor: Some aspects of how we track suicides from your living mob to
your observer have changed- please do let us know if anything has broken
via a GitHub Issue Report.
/🆑
There's probably some technical improvements that can be made in some
parts of the code I reworked to accommodate this change, do let me know
if you spot any easy ones (or fuckups). a lot of excess comes from the
fact that any step in the TRAIT framework trusts that you are passing in
a valid datum (or subtype) so that's a thing
This builds on what #69790 did and improved the code even further.
Notable things:
- `Topic()` is a deprecated proc in our codebase (replaced with
Javascript tgui) so it makes sense to rename `canUseTopic` to
`can_perform_action` which is more straightforward in what it does.
- Positional and named arguments have been converted into a easier to
use `action_bitflag`
- The bitflags adds some new checks you can use like: `NEED_GRAVITY |
NEED_LITERACY | NEED_LIGHT` when you want to perform an action.
- Redundant, duplicate, or dead code has been removed.
- Fixes several runtimes where `canUseTopic` was being called without a
proper target (IV drips, gibber, food processor)
- Better documentation for the proc and bitflags with examples
## About The Pull Request
Make the following list of things that can only be cooked in the
microwave currently also able to be cooked in an oven:
Uncooked rice
Raw spaghetti
Wet leather (YUM!)
Aloe
Onion slices
Cheese curds
Eggs, rotten or not
Ready donk
## Why It's Good For The Game
We've already got stuff that's microwave-oven interchangeable (donk
pockets), sometimes you don't have a microwave and you're just locked
out of more than a few recipes because something that could easily be
made in an oven isn't coded to be. The simple solution is just not have
that be the case.
## Changelog
🆑
qol: A few recipes that were microwave only (like boiling rice, heating
ready donk, so on) can now also be made in an oven
/🆑
Found out poison berry juice existed from the wiki and code diving,
however, only poison berries juice into it. Death berries, despite their
stronger poison, juice into normal berry juice instead. This changes
that to have death berries also juice into poisoned juice.
Mostly a consistency change, it doesn't make sense for the berry with
the stronger poison to not juice into something poisonous as well, when
a berry that's less poisonous does do so. For transparency's sake, this
will make the death berry marginally stronger, as with plant traits you
can get the juiced reagent inside of a plant without juicing it.
- Chocolate boxes now contain bonbons (formerly tiny chocolates),
truffles, and peanut butter cups
- Slices of bread now taste like their respective breads instead of
tasting "indescribable"
- Fiesta skewers have food categories now
- Misc food file has had more split out of it into sweets.dm,
vegetables.dm, and packaged.dm
- Removed a bunch of redundant food_reagent code
- Changed the sugar in clown cakes' food_reagents to banana juice
- Increased the amount of vitamin in pound cakes (it's four whole cakes
and the amount of vitamin doesn't go up?)
I broke it in #72220
Thanks to @Fikou for catching this
list(variable = 0.1) doesnt work on byond, so I last-minute improvised
and changed it to
list("[variable]" = 0.1), using a string instead of a typepath. I
already tested it thoroughly so decided it was probably good without
thinking of it anymore
🆑
fix: fixes pod blood I swear
/🆑
Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>
## About The Pull Request
Updated crafting menu, adding a lot of new functions and recipes that
were not in the crafting menu before.
<img alt="cult"
src="https://user-images.githubusercontent.com/3625094/206009533-aec3a1dd-cbe5-45eb-8515-1b75fabb65c5.PNG">
<img alt="nH77dLyyGx"
src="https://user-images.githubusercontent.com/3625094/206009786-b6706f70-0599-40bf-b051-8f499de43abd.png">

https://user-images.githubusercontent.com/3625094/206009841-738e4a03-0660-45b7-8d83-15eeb6501967.mp4
## Why It's Good For The Game
It is easier to use, and it has a lot of recipes that were spread
throughout the game, some of which weren't even on the wiki.
Crafting and cooking now count about 1200 recipes in total, including
conditionally available ones.
## Changelog
🆑
qol: Rewrote the crafting/cooking menu UI
qol: Split crafting and cooking menus in two different menus
qol: Crafting is no longer blocking the entire UI, only the "Make"
buttons are disabled
qol: Added stack crafting recipes to the crafting menu
qol: Added cooking recipes that were absent in the crafting menu before
(tool recipes, machine recipes, reactions)
qol: Added option to search recipes by title
qol: Added option to filter recipes by required materials/ingredients
qol: Added food types to the cooking menu, highlighting diet of your
species (liked, disliked foods)
qol: Added total nutrition value of the result to the cooking menu
qol: Added option to filter cooking recipes by the food type of the
resulting food
qol: Added "Can make" category that lists all currently craftable
recipes throughout all categories
refactor: changed categories and reshuffled some items in them
code: Reagents now have default container to get an icon from the
reagent datum
code: Objects now have `desc_controls` var for OOC information about
mouse controls that are visible on examine, but not in the description
fix: Fixed alignment on many food icons
fix: Fixed missing icon for beef stroganoff
/🆑
Co-authored-by: tattle <66640614+dragomagol@users.noreply.github.com>
This one is fun.
On every /turf/Initialize and /atom/Initialize, we try to set
`smoothing_groups` and `canSmoothWith` to a cached list of bitfields. At
the type level, these are specified as lists of IDs, which are then
`Join`ed in Initialize, and retrieved from the cache (or built from
there).
The problem is that the cache only misses about 60 times, but the cache
hits more than a hundred thousand times. This means we eat the cost of
`Join` (which is very very slow, because strings + BYOND), as well as
the preliminary `length` checks, for every single atom.
Furthermore, as you might remember, if you have any list variable set on
a type, it'll create a hidden `(init)` proc to create the list. On
turfs, that costs us about 60ms.
This PR does a cool trick where we can completely eliminate the `Join`
*and* the lists at the cost of a little more work when building the
cache.
The trick is that we replace the current type definitions with this:
```patch
- smoothing_groups = list(SMOOTH_GROUP_TURF_OPEN, SMOOTH_GROUP_FLOOR_ASH)
- canSmoothWith = list(SMOOTH_GROUP_FLOOR_ASH, SMOOTH_GROUP_CLOSED_TURFS)
+ smoothing_groups = SMOOTH_GROUP_TURF_OPEN + SMOOTH_GROUP_FLOOR_ASH
+ canSmoothWith = SMOOTH_GROUP_FLOOR_ASH + SMOOTH_GROUP_CLOSED_TURFS
```
These defines, instead of being numbers, are now segments of a string,
delimited by commas.
For instance, if ASH used to be 13, and CLOSED_TURFS used to be 37, this
used to equal `list(13, 37)`. Now, it equals `"13,37,"`.
Then, when the cache misses, we take that string, and treat it as part
of a JSON list, and decode it from there. Meaning:
```java
// Starting value
"13,37,"
// We have a trailing comma, so add a dummy value
"13,37,0"
// Make it an array
"[13,37,0]"
// Decode
list(13, 37, 0)
// Chop off the dummy value
list(13, 37) // Done!
```
This on its own eliminates 265ms *without space ruins*, with the
combined savings of turf/Initialize, atom/Initialize, and the hidden
(init) procs that no longer exist.
Furthermore, there's some other fun stuff we gain from this approach
emergently.
We previously had a difference between `S_TURF` and `S_OBJ`. The idea is
that if you have any smoothing groups with `S_OBJ`, then you will gain
the `SMOOTH_OBJ` bitflag (though note to self, I need to check that the
cost of adding this is actually worth it). This is achieved by the fact
that `S_OBJ` simply takes the last turf, and adds onto that, meaning
that if the biggest value in the sorting groups is greater than that,
then we know we're going to be smoothing to objects.
This new method provides a limitation here. BYOND has no way of
converting a number to a string at compile time, meaning that we can't
evaluate `MAX_S_TURF + offset` into a string. Instead, in order to
preserve the nice UX, `S_OBJ` now instead opts to make the numbers
negative. This means that what used to be something like:
```dm
smoothing_groups = list(SMOOTH_GROUP_ALIEN_RESIN, SMOOTH_GROUP_ALIEN_WEEDS)
```
...which may have been represented as
```dm
smoothing_groups = list(15, MAX_S_TURF + 3)
```
...will now become, at compile time:
```dm
smoothing_groups = "15,-3,"
```
Except! Because we guarantee smoothing groups are sorted through unit
testing, this is actually going to look like:
```dm
smoothing_groups = "-3,15,"
```
Meaning that we can now check if we're smoothing with objects just by
checking if `smoothing_groups[1] == "-"`, as that's the only way that is
possible. Neat!
Furthermore, though much simpler, what used to be `if
(length(smoothing_groups))` (and canSmoothWith) on every single
atom/Initialize and turf/Initialize can now be `if (smoothing_groups)`,
since empty strings are falsy. `length` is about 15% slower than doing
nothing, so in procs as hot as this, this gives some nice gains just on
its own.
For developers, very little changes. Instead of using `list`, you now
use `+`. The order might change, as `S_OBJ` now needs to come first, but
unit tests will catch you if you mess up. Also, you will notice that all
`S_OBJ` have been increased by one. This is because we used to have
`S_TURF(0)` and `S_OBJ(0)`, but with this new trick, -0 == 0, and so
they conflicted and needed to be changed.
## About The Pull Request
The barrel was essentially a grinder that also added a lot of wine on
top of other reagents. Now it converts only nutriment and vitamin into
the wine.
Also the Auto-Distilling Composition plant gene didn't make fruit wine
and gave only half of the distilled drink volume.
- Now the fermentation is consistent and it happens in one place - the
`ferment()` proc of the plant. Both gene and barrel use it.
- Added some sounds and ballon alerts.
- Increased the barrel volume to 600, as other stationary reagent
containers have even more.
https://user-images.githubusercontent.com/3625094/203582992-8d31cff6-15bd-416f-b2fb-c7a0f6cfbcb4.mp4
## Why It's Good For The Game
Barrels are cute, we should use them more.
## Changelog
🆑
qol: barrel works with the plant bag now
balance: barrel volume increased to 600 units
fix: barrel now properly converts nutriments into wine
fix: added 4% nutriments to sugar cane, to allow rum creation
refactor: barrel logic and fermentation refactoring
/🆑
## About The Pull Request
A side effect of my pizza PR #71202 I added contextual screentips as
part of processable.dm. In doing this, I noticed that with a few
exceptions, almost every single bread and cake type copies the proc
exactly the same for every single child of cake or bread, so I put the
proc on the parent of bread and cake and gave them slice_types, making
them more similar to pizza.dm
For everything else I've changed the default that I put in
processable.dm into "slice" or "cut" for things that use the knife and
"flatten" for things that use the rolling pin.
Finally, you can slice bread with saws now, because I think its silly
that only pizza gets this luxury.
## Why It's Good For The Game
Because it wasnt the focus of #71202 I didn't mess with screentips
outside of the pizza file a lot, but now that it's merged I figure I
should go and do that.
As Bread and Cake's processables are almost fully standardized it seems
silly for them to call on the proc 12 times in the same document so I
did this, which also allows for more versatility in editing how they
work as well allow people to, if they want to, add more tool behaviours
in the future without adding in 12 lines of code. Also means that people
who want to add new cake or bread have one less thing to do.
## Changelog
🆑
add: you can saw bread with a saw into bread slices
qol: added screentip verbs to a bunch of food files
code: bread and cake now have slice types and all only have one call on
the processable.dm proc
/🆑
- Makes QDELETED use isnull(x) instead of !x, giving about 0.2 to 0.25s
of speed.
- Make disposal constructs only update icon state rather than go through
expensive overlay code. Unfortunately did not have much effect, but is
something they should've been doing nonetheless.
- Makes RegisterSignal only take signals directly as opposed to
allocating a fresh list of signals. Very few consumers actually used
this and it costs about 0.4s. Also I think this is just a bad API anyway
and that separate procs are important
`\bRegisterSignal\((.*)list\(` replaced with `RegisterSignals($1list(`
## About The Pull Request
Right now most growing plants have an 8 pixel gap at the bottom, to
account for the offset of either soil or a hydroponics tray. This limits
plants to being, at most, 24 pixels high.
Some current plants go below 8 pixels, and so their offsets have been
adjusted accordingly. Also removes some unused mold and vine sprites.
## Why It's Good For The Game
Spriters have more freedom to have their plants be taller or more
dangly.
## Changelog
No player-facing changes
Co-authored-by: tattle <article.disaster@gmail.com>
Makes the code compatible with 515.1594+
Few simple changes and one very painful one.
Let's start with the easy:
* puts call behind `LIBCALL` define, so call_ext is properly used in 515
* Adds `NAMEOF_STATIC(_,X)` macro for nameof in static definitions since
src is now invalid there.
* Fixes tgui and devserver. From 515 onward the tmp3333{procid} cache
directory is not appened to base path in browser controls so we don't
check for it in base js and put the dev server dummy window file in
actual directory not the byond root.
* Renames the few things that had /final/ in typepath to ultimate since
final is a new keyword
And the very painful change:
`.proc/whatever` format is no longer valid, so we're replacing it with
new nameof() function. All this wrapped in three new macros.
`PROC_REF(X)`,`TYPE_PROC_REF(TYPE,X)`,`GLOBAL_PROC_REF(X)`. Global is
not actually necessary but if we get nameof that does not allow globals
it would be nice validation.
This is pretty unwieldy but there's no real alternative.
If you notice anything weird in the commits let me know because majority
was done with regex replace.
@tgstation/commit-access Since the .proc/stuff is pretty big change.
Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
When a food feature PR and a food refactor come together, and get merged
without re-running checks, something very funny happens.
A merge skew.
Edible component uses inherent component so this is fine.
About The Pull Request
Adds a skillchip to the chef's vendor. This vendor allows the chef to kiss their food to deliver a chef's kiss.
Chef's kissing your food will add the "love" reagent to the food, which makes people much happier when they eat it. Be careful, overdosing on love can cause heart attacks.
Refactors microwaving.
Separates microwaving out of the edible component and makes it its own element, like grillable and bakeable.
Also removes some magic numbers from microwave code.
Code improvements all around baking and grilling code.
Refactors edible component inheritance.
Inheriting the edible component is now a viable way to cleanly add food types, flags, and callbacks. This makes it much much easier to change the values of an edible item without adding hacky signals / procs / getcomponent.
Why It's Good For The Game
Emergent chef gameplay.
Being able to further enhance your food with mood buffs.
Better code.
Changelog
cl Melbert
add: Chefs can now make food with love. They can purchase a skillchip from their vendor which enhances their kiss emote. Using your kiss on food you create will add a special reagent to it which makes it nicer.
refactor: Separated Microwavable from the Edible component, refactored microwave act to accompany this
refactor: Refactored how grilled items are generated
refactor: Refactored how silver slime food items are generated
refactor: Refactored how edible items inherit new edible statuses
code: Removed some magic numbers from microwaves
code: General code improvements for grillable / bakeable / etc
/cl
## About The Pull Request
Clown's liver makes them like bananas, ignoring their racial food
preferences.
## Why It's Good For The Game
I don't think clown moths should vomit from eating bananas. They are
clowns, after all.
Also clowns are healed from eating them, so it's a bit silly that they
vomit from their funny medicine.
## Changelog
🆑
balance: Non-human clowns enjoy eating bananas now.
/🆑
Töchtaüse berry juicer fix
removed grind_results since it's redundant and removed the itching powder reagent from the juice_results variable. Added nutriment to Töchtaüse berries for juicing purposes
Splits head dmi into separate files for both mob and obj icons. Kept similar to suit split categorization + some more. New files include beanie, bio, chaplain, costume, cowboy, default, hats(softcaps, fedoras, head caps, generic hats), helmet(helmets and other armored headgear/hoods), spacehelm, utility(hardhats, mostly work related hats), wizard.
Moves animal/pet head sitting icons to 1 folder, pets_head.dmi
Renames PAI head sitting icon file to pai_head.dmi
fix: Fixed a bunch of missing inhand icons.
fix: Fixed cables in electrical toolboxes not randomizing their colors.
fix: Fixed the wrong colored icon showing when trying to make cable cuffs out of cables.
fix: The collectable SWAT helmet is now using the proper icon again!
refactor: Pipecleaners and power cables now share a unified color system, so they're once again available in ALL the same colors.
imageadd: Updated the screwdriver belt overlay to represent the newer sprite.
imageadd: Added a bunch of new inhand icons. Special thanks to Twaticus for doing the helmets! <3
fix: Wirecutters now have an icon when inside a belt again!
admin: Added a new omnitool subtype that allows you to spawn all items in a typepath!
fix: Explorer gaskmasks now properly reflect their adjusted state when held.
fix: Fixed balaclavas having the wrong icon when pulled up.
fix: Fixed the base energy sword (admin spawn only) being invisible.
fix: The rainbow energy sword is now a little bit more rainbowy!
fix: Fixed an tk exploit with orange handcuffed shoes.
fix: The traitor outfit in the select equipment panel is now actually functional!
* canUseTopic now uses TRUE/FALSE instead of defines that just say TRUE
The most idiotic thing I've seen is canUseTopic's defines, they literally just define TRUE, you can use it however you want, it doesn't matter, it just means TRUE. You can mix and match the args and it will set that arg to true, despite the name.
It's so idiotic I decided to remove it, so now I can reclaim a little bit of my sanity.
* Makes flags properly check themselves
Byond ref: https://www.byond.com/docs/ref/#/operator/&
Basically, flags should use & instead of ==
We can have more than 1 slot on any item, so it's preferred that we do this instead. Even if it doesn't immediately fix any problems, it's something that should be the standard anyways to prevent it from ever being a problem.
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
About The Pull Request
I've reworked multiz. This was done because our current implementation of multiz flattens planes down into just the openspace plane. This breaks any effects we attach to plane masters (including lighting), but it also totally kills the SIDE_MAP map format, which we NEED for wallening (A major 3/4ths resprite of all wall and wall adjacent things, making them more then one tile high. Without sidemap we would be unable to display things both in from of and behind objects on map. Stupid.)
This required MASSIVE changes. Both to all uses of the plane var for reasons I'll discuss later, and to a ton of different systems that interact with rendering.
I'll do my best to keep this compact, but there's only so much I can do. Sorry brother.
Core idea
OK: first thing.
vis_contents as it works now squishes the planes of everything inside it down into the plane of the vis_loc.
This is bad. But how to do better?
It's trivially easy to make copies of our existing plane masters but offset, and relay them to the bottom of the plane above. Not a problem. The issue is how to get the actual atoms on the map to "land" on them properly.
We could use FLOAT_PLANE to offset planes based off how they're being seen, in theory this would allow us to create lens for how objects are viewed.
But that's not a stable thing to do, because properly "landing" a plane on a desired plane master would require taking into account every bit of how it's being seen, would inherently break this effect.
Ok so we need to manually edit planes based off "z layer" (IE: what layer of a z stack are you on).
That's the key conceit of this pr. Implementing the plane cube, and ensuring planes are always offset properly.
Everything else is just gravy.
About the Plane Cube
Each plane master (except ones that opt out) is copied down by some constant value equal to the max absolute change between the first and the last plane.
We do this based off the max z stack size detected by SSmapping. This is also where updates come from, and where all our updating logic will live.
As mentioned, plane masters can choose to opt out of being mirrored down. In this case, anything that interacts with them assuming that they'll be offset will instead just get back the valid plane value. This works for render targets too, since I had to work them into the system as well.
Plane masters can also be temporarily hidden from the client's screen. This is done as an attempt at optimization, and applies to anything used in niche cases, or planes only used if there's a z layer below you.
About Plane Master Groups
BYOND supports having different "maps" on screen at once (IE: groups of items/turfs/etc)
Plane masters cannot cover 2 maps at once, since their location is determined by their screen_loc.
So we need to maintain a mirror of each plane for every map we have open.
This was quite messy, so I've refactored it (and maps too) to be a bit more modular.
Rather then storing a list of plane masters, we store a list of plane master group datums.
Each datum is in charge of the plane masters for its particular map, both creating them, and managing them.
Like I mentioned, I also refactored map views. Adding a new mapview is now as simple as newing a /atom/movable/screen/map_view, calling generate_view with the appropriate map id, setting things you want to display in its vis_contents, and then calling display_to on it, passing in the mob to show ourselves to.
Much better then the hardcoded pattern we used to use. So much duplicated code man.
Oh and plane master controllers, that system we have that allows for applying filters to sets of plane masters? I've made it use lookups on plane master groups now, rather then hanging references to all impacted planes. This makes logic easier, and prevents the need to manage references and update the controllers.
image
In addition, I've added a debug ui for plane masters.
It allows you to view all of your own plane masters and short descriptions of what they do, alongside tools for editing them and their relays.
It ALSO supports editing someone elses plane masters, AND it supports (in a very fragile and incomplete manner) viewing literally through someone else's eyes, including their plane masters. This is very useful, because it means you can debug "hey my X is yorked" issues yourself, on live.
In order to accomplish this I have needed to add setters for an ungodly amount of visual impacting vars. Sight flags, eye, see_invis, see_in_dark, etc.
It also comes with an info dump about the ui, and plane masters/relays in general.
Sort of on that note. I've documented everything I know that's niche/useful about our visual effects and rendering system. My hope is this will serve to bring people up to speed on what can be done more quickly, alongside making my sin here less horrible.
See https://github.com/LemonInTheDark/tgstation/blob/multiz-hell/.github/guides/VISUALS.md.
"Landing" planes
Ok so I've explained the backend, but how do we actually land planes properly?
Most of the time this is really simple. When a plane var is set, we need to provide some spokesperson for the appearance's z level. We can use this to derive their z layer, and thus what offset to use.
This is just a lot of gruntwork, but it's occasionally more complex.
Sometimes we need to cache a list of z layer -> effect, and then use that.
Also a LOT of updating on z move. So much z move shit.
Oh. and in order to make byond darkness work properly, I needed to add SEE_BLACKNESS to all sight flags.
This draws darkness to plane 0, which means I'm able to relay it around and draw it on different z layers as is possible. fun darkness ripple effects incoming someday
I also need to update mob overlays on move.
I do this by realiizing their appearances, mutating their plane, and then readding the overlay in the correct order.
The cost of this is currently 3N. I'm convinced this could be improved, but I've not got to it yet.
It can also occasionally cause overlays to corrupt. This is fixed by laying a protective ward of overlays.Copy in the sand, but that spell makes the compiler confused, so I'll have to bully lummy about fixing it at some point.
Behavior changes
We've had to give up on the already broken gateway "see through" effect. Won't work without managing gateway plane masters or something stupid. Not worth it.
So instead we display the other side as a ui element. It's worse, but not that bad.
Because vis_contents no longer flattens planes (most of the time), some uses of it now have interesting behavior.
The main thing that comes to mind is alert popups that display mobs. They can impact the lighting plane.
I don't really care, but it should be fixable, I think, given elbow grease.
Ah and I've cleaned up layers and plane defines to make them a bit easier to read/reason about, at least I think.
Why It's Good For The Game
<visual candy>
Fixes#65800Fixes#68461
Changelog
cl
refactor: Refactored... well a lot really. Map views, anything to do with planes, multiz, a shit ton of rendering stuff. Basically if you see anything off visually report it
admin: VV a mob, and hit View/Edit Planes in the dropdown to steal their view, and modify it as you like. You can do the same to yourself using the Edit/Debug Planes verb
/cl
About The Pull Request
Not without the help of my friend spriter, I added cucumbers, their seeds, the cultivation itself, so that they could be pickled and washed with a brine jar. I also added a Danish hot dog because it required cucumbers (perhaps that was the end goal), changed a couple of recipes to include cucumbers or pickles. Cucumbers have been added to both cargo orders and bounty cubes, as well as for the food order console
I think the Cucumber Update deserves its plush toy.
gg18b4b2cab0
Why It's Good For The Game
I think more food and drink... would add quite a nice role playing experience, and additional gameplay for hydroponics.
Changelog
cl Vishenka0704 and Ying-The-Pando
add: Cucumbers and pickles
add: Danish hot dog
balance: add cucumbers in dishes where they need
qol: add to bounty cubes, orders - new vegetables
/cl
Moves singulo and supermatter dmis into obj/engine, renamed from obj/tesla_engine
Moves Halloween, Christmas, and misc holiday items to obj/holiday
Moves lollipops to obj/food
Moves crates, closets, and storage to obj/storage
Moves assemblies to obj/assemblies
Renames decals.dmi to signs.dmi ...because they're signs and not decals
Moves statues, cutouts, instruments, art supplies, and crayons to obj/art
Moves balloons, plushes, toys, cards, dice, the hourglass, and TCG to obj/toys
Moves guns, swords, shields to obj/weapons
Bananas now have a 1% chance to be bananarangs on initialization. The description is altered to make it slightly easier to notice, but otherwise there is no indication beyond throwing it.
bananarang hehe :)
Can be used for entertainment, bargaining, or engaging with a rarely seen component within the sandbox.
Bananas now have a 1% chance to be boomerang-bananas. These look identical to normal bananas, aside from a slightly unique examine text. Make sure to check your bananas before peeling it to slip the HOS, you may just have a rare item on your hands.
* Removes ComponentInitialize()
Completely removes ComponentInitialize() as a proc, which was called on every single atom in the game, twice in some instances (like new players), over something that can already be done with Initialize().
This is the second attempt at doing this, after the first attempt fell apart for some reason. This time it was way easier though, since storages are no longer a Component.
* update icon blocker added before calling parent
* Update code/game/machinery/porta_turret/portable_turret.dm
Co-authored-by: san7890 <the@san7890.com>
* adds a mapload while I'm here
* moves human mood
* Does some UNRELATED thing to the PR
Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>
Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>
About The Pull Request
Mood was abusing signals and get component pretty badly, so I redid it as a datum to stop this.
Why It's Good For The CODEBASE
Better code pratices, also gives admins easier tools to manage mood
Changelog
cl
admin: Added two new procs into the VV dropdown menu to add and remove mood events from living mobs.
/cl
* Splits up 'gross' food from 'carrion'
* Adds a couple of missed burgers.
Moths dislike Carrion rather than it being poison to them.
* BEES is now BUGS
* It's always safe and a good idea to use find/replace