Decrease the pluoxium produced when exposing co2 to the SM by 5 times.
Decrease the co2 consumed by that process by half
CO2 setups were getting much harder to maintain due to the increased consumption of co2 and production of pluoxium at high level setups. This allows a more fine tuning of the gases and rebalances the gases production/consumption to be around the old levels (pre rads)
About The Pull Request
Simply converts all instances of soundkeys that use get_sfx from strings into defines.
E.g. "sparks" is now SFX_SPARKS
Why It's Good For The Game
It makes life a lot easier when you're looking for a sound effect. You just type SFX_ and you get suggestions in VSC. Plus, it looks better.
image
Changelog
Not player facing.
How do I play/test/operate this?
Download NT Frontier on any modular computers. It should debrief you on what experiments are available and how to publish.
If you want to do a bomb experiment, make sure it's captured by the doppler array (as usual) and then print the experiments into a disk and publish it.
If you want to do a gas experiment, make the gas and either pump it into a tank and 1) overpressurize it with a "clear" gas like N2 or 2) overpressurize tanks with the gas itself. Make sure you do the overpressurizing in the compressor machine. When tanks are destroyed/ejected leaked gas will get recorded. Print it into a disk and publish it.
For publication, the file needs to be directly present inside the computer's HDD. This means you need to copy it first with the file manager.
Fill the data (if desired, it will autofill with boiler plate if you dont) and send away!
Doing experiments unlock nodes, while doing them well unlocks boosts (which are discounts but slightly more restrictive) which are purchaseable with NT Frontier.
If you are testing this and have access to admin tools, there are various premade bombs under obj/effect/spawner/newbomb
A doc I wrote detailing the why and what part of this PR.
https://hackmd.io/JOakSYVMSh2zU2YL5ju_-Q
---
# Intro
## The Problem(s)
Ordnance, (previously toxins) seems to lack a lot of content and things to do. The gameplay loop consists of making a bomb and then sending it off for credits or using it to refine cores. Ordnance at it's inception originally relies on players experimenting and finding the perfect mix over multiple rounds, but once the recipe for a "do-everything" mix got out, the original charm of individual discoveries becomes meaningless.
Another issue with ordnance is the odd difficulty curve. As a new player, ordnance is almost impossible to decipher, but once you watch a tutorial or read a wiki and can mail a 50k into space, there pretty much isn't anything else to do. Most players will be satisfied at this point without the gameplay loop encouraging them to understand or play more. The only thing you can do afterwards is to sink your teeth in and understand why that particular mix explodes the way it does. This again has a significant difficulty curve, but if you do that, the department doesn't acknowledge or reward that in any way. There are pretty much two huge spikes, with the latter one not really existing inside the department.
TLDR:
* The content being same-y over rounds.
* Odd difficulty curve:
1. A new player is oblivious to everything.
2. Those in the middle can repeat the final goal consistently without needing to understanding why
3. There is nothing to justify spending more time in the department after reaching the midgame.
## Abstract
Scientific Papers aim to add a framework to run multiple experiments in ordnance. Adding more experiments scattered across various atmospheric aspects might allow players of various knowledge levels to still have something engaging to do. A new player should have an easier challange than to mail a 50K. While those that already can make bombs should have an easier time understanding why their bombs explode the way it does. Once they fully understand why, they can set their sights on taking advantage of another reaction to set their bomb off or hone one particular reaction down.
## Goals
* Have some intro-level challanges for new players.
* Have some semblance of late-game challanges for more experienced players.
* Explain the mechanics better for those in the middle of the road.
* Incentivize trying new things out in the department.
* Better integrate Ordnance with Experisci
## Boundaries / Dont's
* Do not incentivize people to learn ordnance by using PvP loots.
* Do not shake or change the reaction system by a huge amount.
* Disincentivize having a single god-mix that does everything.
****
# Main design pillars
## A. Framework surrounding the experiments
### A.1. New experiments
Add new experiments to the ExperiSci module. These will come in two flavours: New explosions to do, and various gas synthesis experiments. Both of these are actually supported by the map layout of ordnance right now, but there is no reason to do anything outside of making a 50k as fast as possible.
### A.2. Rewards for experiments: Cash and Techweb Boosts.
Scientific papers will add a separate experiment handling system. A single experiment will be graded into various tiers, each tier corresponding to the explosion size or amount of gas made. Doing any tier of a specific experiment will unlock the discount for that specific reactions. A single explosion **WILL NOT** do multiple experiments (or even tiers) at once.
On publication, a partner can be selected. A single partner only has a specific criteria of experiments they want. The experiments will then be graded on "how good they are done", with the criteria being more punishing as tier increases. Publication will then reward scientific cooperation with the partnered partner. Players can spend this cooperation on techweb boosts. Techweb boosts are meant to be subservient to discount from experiments and will not shave a node's price to be lower than 500 points.
**Experiments will only unlock nodes, discounts are handled through this boost system.**
This is more for maintainability than anything.
### A.3. On Tedium
*This is a note on implementation more than anything, but I think this helps explains why several things are done.*
Due to the nature of atmospheric reactions in the game (they're all linear), tedium is a very important thing to consider. An experiment should have a sweet spot to aim for, but there should not be a point where further mastery is stopped dead on it's track with a reward cap.
Scientific Papers attempts to discourage this behaviour by having the "maximum score" scale off to infinity but with the rewards being smaller and smaller. The sweet spot is always there to aim for and should be well communicated with players, but on their last submission of an experiment topic players should be encouraged to do their best. There should always be a reward for pushing the system to it's limit as long as it doesn't completely nullify the other subdepartments. This is the reason why there is a hard limit on the number of publications and why the score calculation is a bit more complex than it needed to be.
## B. Gas Synthesis (Early-Mid Game)
Scientific papers will add one new machine that requests a tank to release x amounts of y gas. This will be accomplished by adding a tank pumping machine which will either burst or explode a tank, releasing the gas inside. The gas currently requested are BZ, Nitryl, Halon and Nob.
The overarching goal of this compressor machine is to present a gas synthesis challange for the players and to get them more accustomed to how a tank explodes. The gas synthesis part can always be changed in order to reflect the current state of atmospheric reactions.
## C. Explosion Changes (Mid-Late Game)
### C.1 Cause and effect.
The main theme of the explosion changes is establishing cause and effect of explosions. Reactions that happens inside a tank that's going to explode will be recorded and forwarded to a doppler array. Some experiments will require only a single cause to be present (think of it as isolating a variable). This is currently implemented for nobliumformation and pressure based bombs. Having other reactions occuring besides noblium formation will fail the first one, while having any reactions at all will fail the second one.
Adding more explosions here will be a slight challange because as of now the game has only two reactions that can reliably make an explosion.
### C.2 Tools upgrade.
Doppler array has now been retrofitted to state the probable cause of an explosion, be it reactions or just overpressurization on gas merging. These should help intermediate players figure out what is causing an explosion.
Added a new functionality to the implosion compressor:
Basically performs the gas merging and reaction that TTV does in a machine and reports the results back as if someone uses an analyzer on them. Here to give players feedback so they can try and understand what is actually going on in a bomb.
## D. Player Interaction
There should be more room for more than 1 player to play ordnance simultaneously. Previously players are also able to split tasks, but this rarely happens because tritium synthesis needs only the gas chamber to be reconfigured. Now, different players can pick different experiments and work on them. Players can also do joint tasks on one single experiment. Gases like noblium will need tritium production and also a cooling module online.
Ordnance can also coordinate with their parent department on what they really need, be it money or research bonuses.
# Potential Changes
The best-case changes that can be implemented if the current roster of content isn't enough is more reactions that can be used in bombs. Eliminating bombs entirely goes against the spirit of the subdepartment, while adding new ones will need a lot of care and consideration.
Another possible change is to implement a "gas payload" bomb. Bombs that has a set number of unreacting gas inside that will increase the heat capacity, reduce the payload, and neccesitates more bespoke mixes.
Adding more gas synthesis experiments is discouraged. The main focus of ordnance should be bombs, with gas synthesis being a side project for ordnance. These are present to ease the introduction to bombs and provide some side content.
There should be a somewhat well-justified goal in adding new synthesis experiments: e.g. BZ is there as a "tutorial" gas, Nitryl to introduce players to cooling/heating mixes, Halon to a more efficient tritium production, and Nob as a nudge to nobformation bombs and mastery over other aspects.
# Conclusion / Summary
Add more experiments to ordnance that players can take, accomplish this by:
1. Making the players perform gas synthesis or make bombs.
2. Have them collect the data, see if it fits the criteria. Explain why if it fits and why if it doesn't.
3. Have the player publish a paper.
Reward them based on how well did they do, give players agency both on the experiment phase and also publication phase.
---
TLDR: Added new experiment to toxins, added the framework for those experiments existing. Experiments comes in gas synthesis and also bombs but with more parameters. Experiments needs to be published through papers, various choices to be made there.
Implementation notes:
Because of how paper works, ordnance experiments are handled outside of experiment_handler components. My reasoning for this is twofold:
The experiments will be completed manually on publication and if the experiment isn't unlocked yet it will still be completed.
Experiment handler datums have several procs which require an atom-level parent, and I figured this is the most sensible and cleanest way to implement this without changing the experiment handler datum too much.
Small change to /obj/machinery/proc/power_change() signal ordering to adjust the state first and then send the signal. Didn't found any other usage of this signal except mine but barge down my door if it broke something.
Rewrote the ttv merge_gases() code to be slightly more readable.
A small code improvement for thermomachine to use tofixed (my fault).
Ordnance have been updated to enable the publication of papers
Several new explosive and gas synthesis experiments have been added to ordnance
Anomaly compressor has been TGUIzed and now supports simulating the reaction of the gases inside the ttv.
New tank compressor machine for toxins. You can overpressurize tanks with exotic gases and complete experiments.
Several techweb nodes are locked and require toxin experiments to complete.
Toxins can purchase boosts for various techweb nodes.
You no longer need to anchor doppler arrays for it to work.
Doppler array and implosion compressor now supports deconstruction, implosion compressor construction added.
Doppler now emits a red light to denote it's direction and it being on. Doppler not malf.
Implosion compressor renamed to anomaly refinery.
Created a new program tab "Science" for the downloader app. Removed Robotics.
Reworked the code for bombspawner (used in the cuban pete arcade game)
Instead of get_part_ratings() (which is what the RPED uses to decide whether one stock part is better than another) returning rating * maxcharge on cells, it now returns maxcharge + charge. This means the cell of the highest capacity with the most charge will go in first.
Removes manually set ratings on cells in favour of calculating them in Initialize() in a more consistent and logical way. I don't think it's used for anything now anyway.
imageadd: Power cells and the cell charger have been resprited, the charger will now look correct with a much wider variety of non-standard power cells
del: Removed the uncraftable 15k charge high-capacity power cell+, all instances have been replaced with the regular 10k charge high-capacity cell
fix: Erroneous power cell charge indicators have been removed from many non-standard types of power cells
fix: All varieties of marauder mech including the nuke ops mauler come with a bluespace power cell, consistent with other nuke op mechs
fix: Power cell charge indicators will now update while in a cell charger
fix: Potato and other crop batteries will not have their wires disappear when on cell chargers
About The Pull Request
Adds an argument to typecache generation that allows specifying the whether to include/exclude types in the input list.
Also adds another argument to specify whether to remove falsey values after the typecache is generated.
Why It's Good For The Game
Might make zaps slightly faster???
Honestly I just thought it would be a good way to condense some whitelist/blacklist typecache sets.
This adds some new defines and flags for the rotation component that lets us remove lots of c/p code chunks. I also added documentation to all the rotation defines that currently exist and in other spots that had weird behavior.
New rotation flags:
ROTATION_GHOSTS_ALLOWED - checks if ghosts are able to manipulate objects in config and lets them rotate the object
ROTATION_IGNORE_ANCHORED - this skips checking if an object is anchored (which normally prevents us from rotating) Used mainly for chairs.
ROTATION_NO_FLIPPING - this removes the flip verb from possible right click rotation options. Used for pipes that have custom flipping verbs instead
ROTATION_NEEDS_ROOM - this checks if an object needs to have an empty spot available in target direction. Used for windows and railings.
Objects can now be rotated in the direction based on which LMB or RMB you click with when you ALT click it. LMB is counter clockwise. RMB is clockwise. Before some objects could only be rotated clockwise. Now any object that inherits the rotation component can be rotated in either direction.
There was also a bug with wheelchairs that existed from when they were ported over from another codebase. The rotation logic was broken and never allowed anyone to rotate them. This has been fixed.
Rotation for IV_drips was enabled however Alt Click was being used for another proc and rotation was ignored because of this. I removed the rotation component due to this since I didn't want to change the hotkeys for IV drips since those have an actual effect on gameplay interactions while rotation does not.
Fingerprints are no longer added when something gets rotated. Only a few objects had this enabled but I believe this interaction was very spammy and unnecessary. I can readd this as a flag if needed but for now it's removed.
Alert balloons have replaced a lot of rotation to_chat() messages for the same reason as fingerprints. Rotating objects has almost no effect on gameplay and will only clutter a player's message log.
The hotkeys for pipe interactions had to be redone since Alt clicking was already being used in some situations. For regular pipes: Right clicking now changes the pipe layer. Alt clicking rotates the pipe. For Trinary pipes: Right clicking now flips the pipe device. Alt clicking rotates the device.
ComponentInitialize() is a deprecated function and the AddComponent proc was moved to Initialize for several objects.
Adds a basic bucketing system to move loops.
This should hopefully save a lot of cpu time, and allow for more load while gaining better smoothness.
The idea is very similar to SStimer, but my implementation is much more simple, since I have to worry less about long delays and redundant buckets.
Insertion needs to be cheaper too, since I'm making a system that by design holds a lot of looping things
It comes with some minor tradeoffs, we can't have constant rechecking of loops if a move "fails", not that we really want that anyway
We also lose direct control over the timer var, but I think that's better, don't want people manipulating that directly
Not that it even really worked very well back when we did have it
Removes the sleep from singularity code
Rather then using sleep to store the state of our iteration, we instead queue the iteration in a list.
We then use a custom singulo processing subsystem to call our "digest" proc several times per full eat, with the hope of staying on top of
our queue
This rarely happens because the queue is too large, god why is a sm powered singulo 24x24 tiles.
I've also A: cached our dist checks, and B: Added dist checks to prevent attempting to pull things out of range
This might look a bit worse, but it saves a lot of work
Oh right and I made the singulo unable to eat while it still has tiles to digest. The hope is to prevent
overwork and list explosion.
Hopefully this will prevent singulo server stoppage, though I've seen some other worrying things in testing.
This PR allows ethereals to receive and give charge to APCs again. I had to make some design choices due to the fact there is no clear solution with ethereals having an action with two possible outcomes. I moved ethereal APC charging to its own function called from the right click attack hand function.
We were setting the offset to negative values, then checking that against a non negative define
Uses the absolute value to compare instead of the signed value.
fixes#64029 (Springlock MOD module kills you even when you have Memento Mori necklace)
fixes#64136 (modsuits cant run out of charge)
fixes#64158 (trying to install a battery into a modsuit with free storage space places the battery into storage)
fixes#64186 (ModSuits : taking out cell doesn't give it back)
fixes#64161 (Modsuit cores disappear in construction)
makes mod jetpacks show particles indoors
gives the prototype suit back their upgraded cell (they literally lose 1% of power per 3 seconds with their current one)
Fully reworks the kinesis module to not be TK but lamer, it is now a gravitational anomaly locked module.
Unique stuff that can be used in fun scenarios
You can no longer produce oxygen free pluoxium. Adds a min check to prevent creating a significant amount of pluoxium while consuming an insignificant amount of oxygen.
Pluoxium needs oxygen.
* Pipe direction fix. (#1)
* Test
* Test
* Forgot to do this thing.
* Okay
* Why did I do that?
* Arghh
* Not sure how that got here.
* Revert "Pipe direction fix. (#1)" (#2)
This reverts commit 7ffd5b598f9bd598f67f6ba3219079f3c03e2ac4.
* Smart pipes direction fix.
Hi
* Revert "Pipe direction fix. (#1)" (#4)
* Gaming
* Flushed
* Okay
* Changes a number.
Co-authored-by: 170141183460469231731687303715884105727 <58013024+170141183460469231731687303715884105727@users.noreply.github.com>
About The Pull Request
It turns out that when the supermatter is about to explode it spams a div/0 runtime instead of emitting rads. This fixes that.
This also fixes a runtime caused by attempting to walk through an airlock with a cut ID wire since it came up in testing.
Why It's Good For The Game
Less runtimes.
Changelog
cl
fix: The supermatter will once again emit radiation when it is about to explode.
/cl
You can click on things through cameras. This is one of the major appeals of BRPEDs. If you try to shoot at things while using a camera console to aim you will shoot at the angle between the camera you are looking through and the thing you are aiming at. This makes you aim at the thing you are aiming at from the perspective of yourself instead of the camera you are using.
While it would be funny to watch a sniper gun down their own team aiming through a camera bug and shooting in the opposite direction they think they I'd prefer if it actually worked.
Fixes#62794 (Catwalk Tiles placed on the lower level of tram appear to be on the upper level)
Fixes#57654 (Open Space shading not always applied)
Fixes#53666 (When standing on a glass floor above a light on the Z level below you the light effect is rendered above the character. This makes light have ugly glows on the floors above. This also happens with grills and lattice.)
Transparent turfs, catwalks, and lighting overlays were badly broken with MultiZ issues. This fixes any transparent turf to appear and be on the same z-level if it has the turf_transparent element. Catwalks will appear and be on the same z-level as well. They were initially glitching to top z-levels causing people to walk over an illusion that caused them to fall to their deaths.
After I fixed these issues I noticed that lighting overlays were also glitching to top z-levels, which looked rather strange as there were lights in the middle of rooms and hallways with no supporting walls. Lights now appear under the transparent turfs properly.
The mapping icons for catwalks displayed the wrong icon_state so I fixed that too.
I made a big refactor for transparency and catwalks code that had to be done to get all of this to work properly.
You no longer have to be afraid of falling off of glass floors, catwalks, or transparent tiles. Also lighting overlays don't glitch through upper z-levels anymore for transparent tiles.
I'm refactoring proximity monitors and fields, removing lots of bloat from both that's hardly even used. Proximity monitors no longer generate effect objects to track the surrounding area, should be less cpu expensive and easier to maintain (or phase out), read and use.
This PR also adds a couple components which may be needed for future stuff (for starters, the mirror reflection PR #62638 could use the connect_range comp)
Improving old old, ugly old code and adding some useful backend components. Tested and working.
If there is no air on a turf, the supermatter crystal will not produce gases even if powered. This changes that so that it can produce gases while powered if there are none on the turf. It will still take damage in case it doesn't produce gases, or it gets immediately removed.
Although it's unlikely to happen, it will look very weird if the supermatter doesn't produce gas while on a non-space turf while powered, as that situation but with like 0.0001 moles on the turf would cause the SM to immediately go on fire.
a month or two ago i realized that on master the reason why get_hearers_in_view() overtimes so much (ie one of our highest overtiming procs at highpop) is because when you transmit a radio signal over the common channel, it can take ~20 MILLISECONDS, which isnt good when 1. player verbs and commands usually execute after SendMaps processes for that tick, meaning they can execute AFTER the tick was supposed to start if master is overloaded and theres a lot of maptick 2. each of our server ticks are only 50 ms, so i started on optimizing this.
the main optimization was SSspatial_grid which allows searching through 15x15 spatial_grid_cell datums (one set for each z level) far faster than iterating over movables in view() to look for what you want. now all hearing sensitive movables in the 5x5 areas associated with each spatial_grid_cell datum are stored in the datum (so are client mobs). when you search for one of the stored "types" (hearable or client mob) in a radius around a center, it just needs to
iterate over the cell datums in range
add the content type you want from the datums to a list
subtract contents that arent in range, then contents not in line of sight
return the list
from benchmarks, this makes short range searches like what is used with radio code (it goes over every radio connected to a radio channel that can hear the signal then calls get_hearers_in_view() to search in the radios canhear_range which is at most 3) about 3-10 times faster depending on workload. the line of sight algorithm scales well with range but not very well if it has to check LOS to > 100 objects, which seems incredibly rare for this workload, the largest range any radio in the game searches through is only 3 tiles
the second optimization is to enforce complex setter vars for radios that removes them from the global radio list if they couldnt actually receive any radio transmissions from a given frequency in the first place.
the third optimization i did was massively reduce the number of hearables on the station by making hologram projectors not hear if dont have an active call/anything that would make them need hearing. so one of hte most common non player hearables that require view iteration to find is crossed out.
also implements a variation of an idea oranges had on how to speed up get_hearers_in_view() now that ive realized that view() cant be replicated by a raycasting algorithm. it distributes pregenerated abstract /mob/oranges_ear instances to all hearables in range such that theres at max one per turf and then iterates through only those mobs to take advantage of type-specific view() optimizations and just adds up the references in each one to create the list of hearing atoms, then puts the oranges_ear mobs back into nullspace. this is about 2x as fast as the get_hearers_in_view() on master
holy FUCK its fast. like really fucking fast. the only costly part of the radio transmission pipeline i dont touch is mob/living/Hear() which takes ~100 microseconds on live but searching through every radio in the world with get_hearers_in_radio_ranges() -> get_hearers_in_view() is much faster, as well as the filtering radios step
the spatial grid searching proc is about 36 microseconds/call at 10 range and 16 microseconds at 3 range in the captains office (relatively many hearables in view), the new get_hearers_in_view() was 4.16 times faster than get_hearers_in_view_old() at 10 range and 4.59 times faster at 3 range
SSspatial_grid could be used for a lot more things other than just radio and say code, i just didnt implement it. for example since the cells are datums you could get all cells in a radius then register for new objects entering them then activate when a player enters your radius. this is something that would require either very expensive view() calls or iterating over every player in the global list and calling get_dist() on them which isnt that expensive but is still worse than it needs to be
on normal get_hearers_in_view cost the new version that uses /mob/oranges_ear instances is about 2x faster than the old version, especially since the number of hearing sensitive movables has been brought down dramatically.
with get_hearers_in_view_oranges_ear() being the benchmark proc that implements this system and get_hearers_in_view() being a slightly optimized version of the version we have on master, get_hearers_in_view_as() being a more optimized version of the one we have on master, and get_hearers_in_LOS() being the raycasting version currently only used for radios because it cant replicate view()'s behavior perfectly.
About The Pull Request
Now that radiation waves are gone, the SM isn't capable of generating Pluox, actually the only way to generate Pluoxium is with a reaction mix of O2/Plasma/Tritium at low pressure, something that I assume most of the Atmos players don't even know about as the SM was the main and efficient way to generate Pluox.
The change also removed Pluox as an annoying waste gas on the SM, not the biggest of nerfs but...
So I copied the way the SM reacts with Miasma to generate extra power (bet most people don't know about this either.) for parity on how the SM only reactions work, but with a few changes to work better with a high power charged CO2 SM compared to a Miasma one.
The main change compared to the Miasma reaction is that it scales less with power and more with pressure, a High pressure and low power CO2+O2 SM should be the most efficient/safe way to make Pluox, a different kind of challenge to the low pressure high power CO2 SMs we have already.
Also, the amount of Pluox generated might need tweaks, but it is nothing compared to the production of old Radiation charged SMs.
Why It's Good For The Game
When I was a lil baby Atmos Tech, I looked at the Pluox generation reaction and had such high expectations.
"Wow, I can make more efficient Pluox internals to give away, I can flood the Station with Pluox instead of O2 and it will prevent fires and allow Plasmamen to vibe!"
Such cute thoughts that never really got into reality because the task is gargantuan without much return... still cute thoughts that I hope new Atmos players at least try.
Something something S O U L.
Changelog
cl Guillaume Prata
expansion: After a short break, the Supermatter is back again at the her hard working and slightly different Pluoxium generation business.
/cl
This apparently happened in 58d0f12c5c, four year ago, where a New()
was renamed to Initialize().
Apparently in this case, the second definition runs first, and the first
definition runs in the second's parent call. Since the second immediately
calls the first as a parent call, just merging them with the first's body
first preserves behavior.
This is slightly horrifying.
About The Pull Request
Wall items mostly use the direction from the floor to the wall in the named mapping helper. Wall items mostly use the direction from the wall to the floor for the internal dir variable.
This leads to a headache when it comes to working out what conflicts with what, and what needs placing where.
Wall frames provided a member, inverse, which specified whether or not to invert the direction of the item when looking for conflicts. It was also used to specify whether to look for conflicts outside of the wall (cameras and lights appear external to the wall) or inside the wall (most wall items). This flag was set for Intercoms, APCs, and Lights. Since APCs and Lights expect a floor-to-wall direction, and Intercoms expect a wall-to-floor direction, this means that APCs and Lights were getting the correct direction, and Intercoms were getting the wrong direction.
Some implications of this setup were:
You could build an APC on top of another wall item, provided there was nothing external attached to the wall and the area didn't have an APC.
You could stack Intercoms indefinitely on top of the same wall, provided you weren't in a one-tile wide corridor with something on the opposite wall.
Or both! Here's twenty Intercoms placed on the wall, and a freshly placed APC frame after placing all Intercoms and deconstructing the old APC:
endless-stack-of-intercoms
Not everything used this inverse variable to adjust to the correct direction. For example, /obj/machinery/defibrillator_mount just used a negative pixel_offset to be visually placed in the correct direction, even though the internal direction was wrong, and never set! This also let you stack an indefinite number of defib mounts on the same wall, provided it wasn't a northern wall... except you could do this to northern walls too, since defibs weren't considered a wall item for the purposes of checking collisions at all!
Ultimately, every constructable interior wall item either used this inverse variable to adjust to the correct placement, set a negative pixel_offset variable to have its offset adjusted to the correct placement, or overrode New or Initialize to run its own checks and assignment to pixel_x and pixel_y!
Inventory: Table of various paths, related paths, and the adjustments they used
Unfortunately, untangling /obj/structure/sign is going to be another major headache, and this has already exploded in scope enough already, so we can't get rid of the get_turf_pixel call just yet. This also doesn't fix problems with the special 2x1 /obj/structure/sign/barsign.
Some non-wall items have been made to use the new MAPPING_DIRECTIONAL_HELPERS as part of the directional cleanup.
tl;dr: All wall mounted items and some directional objects now use the same direction that they were labelled as. More consistent directional types everywhere.
Why It's Good For The Game
fml
Changelog
cl
refactor: Wall mounted and directional objects have undergone major internal simplification. Please report anything unusual!
fix: You can no longer stack an indefinite amount of Intercoms on the same wall.
fix: Defibrillator Mounts, Bluespace Gas Vendors, Turret Controlers, and Ticket Machines are now considered wall items.
fix: Wall mounted items on top of the wall now consistently check against other items on top of the wall, and items coming out of the wall now consistently check against other items coming out of the wall.
fix: The various directional pixel offsets within an APC, Fire Extinguisher Cabinet, Intercom, or Newscaster have been made consistent with each other.
fix: The pixel offsets of Intercoms, Fire Alarms, Fire Extinguisher Cabinets, Flashers, and Newscasters have been made consistent between roundstart and constructed instances.
fix: Constructed Turret Controls will no longer oddly overhang the wall they were placed on.
qol: Defibrillator mounts now better indicate which side of the wall they are on.
fix: Some instances where there were multiple identical lights on the same tile have been fixed to only have one.
/cl