Resolves a lot of broken exterior lighting in a few offsites/offships,
inclusive of the Xanu Frigate and Ranger Corvette. Adds a few missing
entry points to the Xanu Frigate so its gunnery nacelles can be shot
from the fore.
As title. I'm not sure why this was set to the layer it was, but it
meant any shutters lowered over airlocks - such as those in both
holodecks - were effectively invisible.
* Please describe the intent of your changes in a clear fashion.
This PR addresses the `Cannot read null.stat_panel` error occurring in
`SSstatpanels/fire()`.
**Root Cause:**
The primary cause was a race condition during client login. A `client`
object was added to `GLOB.clients` in `client/Login()` before its
`stat_panel` member had been fully initialized. This allowed the
`SSstatpanels/fire()` subsystem, which iterates over `GLOB.clients`, to
attempt to access `target.stat_panel.is_ready()` on a `null`
`stat_panel`, leading to a runtime error. Recent changes increasing the
frequency of `stat_panel` updates exacerbated this issue.
**Solution:**
1. **Reordered Client Initialization:** In
`code/modules/client/client_procs.dm`, the line `GLOB.clients += src`
has been moved to occur *after* `stat_panel = new(src, "statbrowser")`
and `stat_panel.subscribe(...)`. This ensures that a client is only
added to the global list once its `stat_panel` is properly instantiated,
eliminating the race condition.
2. **Defensive Null Checks:** Additional null checks for `stat_panel`
have been added in `code/controllers/subsystems/statpanel.dm`:
* In `fire()`, the condition `!target.stat_panel.is_ready()` was updated
to `!target.stat_panel || !target.stat_panel.is_ready()`.
* In `refresh_client_obj_view()`, an early return
`if(!refresh.stat_panel) return` was added.
These defensive checks provide robustness against any future reordering
issues or unexpected scenarios where `stat_panel` might be null.
* Please make sure that, in the case of mapping changes, you include
images of these changes in the PR's description.
* Please make sure to mark your PR as wip or review required by making a
comment with !wip or !review required
* If you include sprites/sounds/... (assets) that you have not created
yourself specify the license and original author below.
* Ensure that you also credit them in the appropriate location /
changelog as specified in the contributor guidelines
### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:
| Path | Original Author | License |
| --- | --- | --- |
| icons/example.dmi | ExamplePerson (Example Station) | CC0 |
Fixes
[SERVER-PROD-1M4](https://aurorastation.sentry.io/issues/7547575486/?seerDrawer=true)
---------
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
* Please describe the intent of your changes in a clear fashion.
This PR addresses a runtime error occurring in `mob/proc/LateLogin()`
when `machine.on_user_login(src)` is called. The error happened when the
`machine` variable on a mob was unexpectedly set to a
`/mob/abstract/ghost/observer` (instead of an `/obj`), typically during
the shared dreaming (Srom) wakeup process.
The `on_user_login()` proc is defined on `/obj` but not on `/mob` types.
The fix adds a type check `isobj(machine)` before attempting to call
`machine.on_user_login(src)` in `code/modules/mob/login.dm`, ensuring
the proc is only invoked when `machine` is indeed an object, thus
preventing the 'undefined proc or verb' runtime.
* Please make sure that, in the case of mapping changes, you include
images of these changes in the PR's description.
* Please make sure to mark your PR as wip or review required by making a
comment with !wip or !review required
* If you include sprites/sounds/... (assets) that you have not created
yourself specify the license and original author below.
* Ensure that you also credit them in the appropriate location /
changelog as specified in the contributor guidelines
### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:
| Path | Original Author | License |
| --- | --- | --- |
| icons/example.dmi | ExamplePerson (Example Station) | CC0 |
Fixes
[SERVER-PROD-2SZ](https://aurorastation.sentry.io/issues/7666863585/?seerDrawer=true)
---------
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
This PR refactors get_pain() to be essentially performance free.
Previously it was a member of the top 5 most expensive procs.
I had to touch a metric shitton of files to make this happen. Notably
get_pain() was also 1/3rd of the entire processing cost for Mobs - Life
* Welding arcs now damage the eyes of visible onlookers within two tiles
who are facing the welder and are not wearing eye protection.
AI usage disclosure: The code for this was created in-part using GPT 5.6
Sol.
* Fixed tails layering oddly in character preview, holograms, photos,
etc.
AI usage disclosure: The code for this was created using GPT 5.6 Sol.
The sprite edits were all done by myself, manually.
Adds the missing [!] to the gravity anomoly overmap icon and a new
psiren overmap icon, so they no longer share an icon with carp.
---------
Signed-off-by: Fyni <itsfyni@gmail.com>
Removes extra grate right above the GTR decal
Fixes broken vent right above the roller bed rack
Removes the medical sign from the recovery room
pharm requests console is no longer mounted on a window in the pharmacy
re-adds a bag of SBS to OR supplies
moves med lobby water cooler to a less weird spot
fixes the fences at the pharmacy desk queue
adds more light to ICU
adds a ringer button to outside of ICU
adds a button to toggle door bolts on the ICU airlock
---------
Signed-off-by: ASmallCuteCat <neofelisnebulosa128@gmail.com>
Co-authored-by: SleepyGemmy <99297919+SleepyGemmy@users.noreply.github.com>
makes `/obj/effect/map_effect/marker/airlock` into `ABSTRACT_TYPE()`
for better organization and stuff
adds:
```
/// External airlock marker, for non-docking non-shuttle airlocks.
/// Just a plain external access airlock.
/obj/effect/map_effect/marker/airlock/external
```
---------
Co-authored-by: DreamySkrell <>
Any ion currently oneshots a mech, by draining it's power cell to zero.
The amount of cell power drained is now random, up to the max charge of
the cell for a heavy EMP.
Up to half the max charge of the cell for a light EMP.
This PR makes EMPs respect energy armour, as the description of energy
armour says they should.
Energy armour is averaged across the mob, weighted for limb size.
This is then the chance to downgrade the EMP.
A heavy EMP can be downgraded into a light EMP, but no further.
A light EMP can either be negated completely, or only affect the mob's
contents.
Eg. A human wearing Ablative armour, (Energy 40), gives a 33% chance to
downgrade a heavy EMP to a light, as it leaves the hands and feet
uncovered.
The same mob struck by a light EMP has a 33% chance to have the EMP only
affect it and not it's contents (internal organs), if that is
successful, there is a further 33% chance to negate the EMP completely.
This means a mech with EM armour is guaranteed to downgrade a heavy EMP
to light, and to ignore light EMPs completely.
All other types of mech armour have Energy 10.
Almost all EMPs are heavy, with the edge of EMP grenades being the only
source of a light EMP.
Ion rifles EMP the target twice, 8 heavy EMP's downgraded to light, will
still seriously damage an unpowered EM armoured mech.
---------
Signed-off-by: FenodyreeAv <fenodyree.av@gmail.com>
* Please describe the intent of your changes in a clear fashion.
Addresses a "list index out of bounds" error occurring in
`obj/item/ammo_pile/proc/remove_ammo` when
`obj/item/ammo_pile/proc/scatter()` was called.
The root cause was a race condition where `scatter()` iterated over the
`ammo` list and called `remove_ammo()` for each item. `remove_ammo()` in
turn called `check_ammo()`, which would `qdel(src)` (and thus empty the
`ammo` list) when only one round remained. This left `scatter()` to
continue its loop and call `remove_ammo()` on an already empty list,
leading to the crash.
The fix rewrites `scatter()` to directly handle the unregistering of
signals, force-moving, and throwing of each bullet. After all bullets
have been processed, the `ammo` list is cleared, overlays are cut, and
the pile is `qdel`'d. This avoids the problematic mid-loop calls to
`remove_ammo()` and `check_ammo()`, preventing the list index out of
bounds error.
* Please make sure that, in the case of mapping changes, you include
images of these changes in the PR's description.
* Please make sure to mark your PR as wip or review required by making a
comment with !wip or !review required
* If you include sprites/sounds/... (assets) that you have not created
yourself specify the license and original author below.
* Ensure that you also credit them in the appropriate location /
changelog as specified in the contributor guidelines
### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:
| Path | Original Author | License |
| --- | --- | --- |
| icons/example.dmi | ExamplePerson (Example Station) | CC0 |
Fixes
[SERVER-PROD-3N](https://aurorastation.sentry.io/issues/7405041136/?seerDrawer=true)
---------
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
* Please describe the intent of your changes in a clear fashion.
This PR addresses a crash (`SERVER-PROD-2R6`) caused by a temperature
mismatch when adding new reagents, particularly in low-volume metabolism
holders.
The root cause was identified as a combination of:
1. A coarse rounding guard in `set_thermal_energy` that discarded
small-but-valid thermal energy changes.
2. A temperature assertion in `add_reagent` that was too sensitive to
floating-point inaccuracies.
3. The `nicotine` reagent lacking an explicit `fallback_specific_heat`.
Changes implemented:
- **`code/modules/reagents/Chemistry-Temperature.dm`**: Modified
`set_thermal_energy` to remove the `round(delta, 1)` guard. Now,
`if(!delta)` is used, allowing small, non-zero energy changes to be
processed.
- **`code/modules/reagents/Chemistry-Holder.dm`**: Updated the
temperature assertion in `add_reagent` from `round(temperature, 1) !=
round(get_temperature(), 1)` to `abs(temperature - get_temperature()) >
0.1`. This provides a more robust, tolerance-based comparison.
-
**`code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm`**:
Added `fallback_specific_heat = 1.67` to
`/singleton/reagent/mental/nicotine` to ensure it has a proper specific
heat value.
* Please make sure that, in the case of mapping changes, you include
images of these changes in the PR's description.
* Please make sure to mark your PR as wip or review required by making a
comment with !wip or !review required
* If you include sprites/sounds/... (assets) that you have not created
yourself specify the license and original author below.
* Ensure that you also credit them in the appropriate location /
changelog as specified in the contributor guidelines
### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:
| Path | Original Author | License |
| --- | --- | --- |
| icons/example.dmi | ExamplePerson (Example Station) | CC0 |
Fixes
[SERVER-PROD-2R6](https://aurorastation.sentry.io/issues/7661064998/?seerDrawer=true)
---------
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
* Please describe the intent of your changes in a clear fashion.
This PR addresses issue SERVER-PROD-12K by correcting a hard delete
warning related to `/mob/living/simple_animal/hostile/carp` during the
carp migration event.
Previously, in `code/modules/events/carp_migration.dm`, the `end()` proc
was calling `qdel(carp_weakref)` instead of `qdel(fish)`. This meant the
weakref datum was being deleted, but the actual carp mob was left
without a proper `qdel()` call, leading to BYOND's garbage collector
performing a 'hard delete' and logging a warning.
The fix changes `qdel(carp_weakref)` to `qdel(fish)` on line 103,
ensuring the carp mob is correctly soft-deleted when the event ends.
* Please make sure that, in the case of mapping changes, you include
images of these changes in the PR's description.
(No mapping changes in this PR)
* Please make sure to mark your PR as wip or review required by making a
comment with !wip or !review required
* If you include sprites/sounds/... (assets) that you have not created
yourself specify the license and original author below.
* Ensure that you also credit them in the appropriate location /
changelog as specified in the contributor guidelines
### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:
| Path | Original Author | License |
| --- | --- | --- |
| icons/example.dmi | ExamplePerson (Example Station) | CC0 |
(No new assets included in this PR)
Fixes
[SERVER-PROD-12K](https://aurorastation.sentry.io/issues/7522667244/?seerDrawer=true)
---------
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
## About PR
Makes it so when a turf calls the overlay subsystem (if overlay layer
was left as default) it'll add overlays slightly above the turf layer.
With this we'll no longer have the silly issue where turf smoothing
overlays appear under the adjacent turfs depending on turf load order
In short, here's what it fixes
Before:
<img width="396" height="601" alt="Screenshot_10"
src="https://github.com/user-attachments/assets/91708402-c6c6-433f-af9f-5293ce926731"
/>
After:
<img width="391" height="598" alt="Screenshot_9"
src="https://github.com/user-attachments/assets/556d48dd-d463-4f76-b075-f0d77340e837"
/>
---
to-do:
- [x] Figure out whether to change `is_plating()` check method or add
the missing `initial_flooring` for every exoplanet turf type since this
plays a role in deciding decal layer, suffer as both paths are equally
agonizing
* Please describe the intent of your changes in a clear fashion.
The `die()` proc for the positronic brain
(`/obj/item/organ/internal/machine/posibrain/die()`) was attempting to
transfer `owner.mind` to `stored_mmi.brainmob` without first checking if
`owner.mind` was null. This led to a runtime error (`Cannot execute
null.transfer to().`) when the IPC mob was mindless (e.g., an NPC, a
disconnected player, or if the mind had already been transferred).
This change adds a null-check (`if(owner.mind)`) around the
`transfer_to()` call in `die()` at line 103 of `posibrain.dm`. This
prevents the error by ensuring the transfer only occurs when a mind
object actually exists, mirroring the safe pattern already present in
the `removed()` proc.
* Please make sure that, in the case of mapping changes, you include
images of these changes in the PR's description.
* Please make sure to mark your PR as wip or review required by making a
comment with !wip or !review required
* If you include sprites/sounds/... (assets) that you have not created
yourself specify the license and original author below.
* Ensure that you also credit them in the appropriate location /
changelog as specified in the contributor guidelines
### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:
| Path | Original Author | License |
| --- | --- | --- |
| icons/example.dmi | ExamplePerson (Example Station) | CC0 |
Fixes
[SERVER-PROD-RG](https://aurorastation.sentry.io/issues/7496141971/?seerDrawer=true)
---------
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
<img width="606" height="144" alt="image"
src="https://github.com/user-attachments/assets/f1c88863-37be-41e0-be79-27fca980a3f3"
/>
This PR adds new "Cross-Role Interactions" for the Mechanical
Engineering skill, with two specific kinds that are aimed at a variety
of different roles.
1. **Bonus damage vs. structures**: Having ranks in MechE makes you deal
bonus damage when melee attacking structures like Airlocks and Windows.
This makes it a desireable niche pick for any kind of job that can see
themself wanting to take a breaching to a room's entrance! For example,
paramedics, shaft miners, and security can all make use of it on
occasion.
2. **Mech Repair Speed**: This one is aimed specifically at Machinists.
Repairing mechs with a welder is no longer instantaneous (That was very
powergamey in practice for 'battle machinists'). Instead it has a repair
speed (and repair amount) that scales with your Mechanical Engineering
skill.
Why MechE and not Robotics? To encourage further "Machinist
Specialization". Machinist players were already pretty naturally
inclined to position their character as either being a Robotics
Specialist, or a Mechatronics Specialist, by sheer virtue of there being
two machinist slots and two noticeably distinctive roles. This
separation of skill interactions is there to further encourage this
degree of separation between machinist skillsets.
As a side note, just so I'm not thoroughly pissing off every machinist
main. As a quality of life improvement, I've made it so that attempting
to repair a mech with a welder will loop the repair until completed or
interrupted.
---------
Signed-off-by: VMSolidus <evilexecutive@gmail.com>
Split this off the larger PR coming that adds the new psychic damage
mechanics to loner, as this is nearly a pure bugfix.
Limitations, mend can't interact with anything not organic, it won't fix
prosthetics, or wounds with embedded objects.
This can leave bleeding wounds if there are serious wounds with shrapnel
in them, I added a message to make it clear that this is intentional
behavior.
The limb-processing PR means that sometimes limbs can get stuck with
pain, which happens occasionally when using mend, but this is fixed in
#22847 so I didn't address it.
changes:
- bugfix: "Fixes the Mend power taking 15 seconds to scan every organ,
even if the organ is healthy."
- bugfix: "Fixes the Mend power not being able to fix blindness."
- bugfix: "Fixes the Mend power not being able to fix heart attacks."
- bugfix: "Fixes the Mend power not being able to fix brute or burn
damage."
- bugfix: "Fixes the Mend power not being able to fix tendons."
- bugfix: "Fixes the Mend power not respecting psychic sensitivity."
- bugfix: "Fixes the Mend power thinking every external organ is
robotic."
This PR moves some parts of the Medical department around, and also
changes the floor decal color to a more unique and less eye-smarting
shade of green.
The ICU and the storage room have been swapped. You no longer have to
trample the GTR to rush a patient to the stasis beds. Antagonists may
also enjoy an easy way to quietly steal some medical items without
having to leave maintenance.
The Medical lobby area has been shrunk to a more reasonable size and is
less of an awkward L-shaped hallway.
Pharmacy has been moved to Recovery Ward's current location, and
Recovery Ward is to the right of the Lobby.
Having to manually open closed circuits and install a battery in each
individual one was pain when cloning large volumes.
Now the circuit printer spawns the circuit with an uncharged battery.
If you want a better battery, or a charged one you still have to take it
out.
**_- bugfix: "Fixes all rubber bullets dealing damage twice."_**
Rubber bullets were dealing their pain damage twice, while checking if
they should shake your screen or not.
_**- bugfix: "Fixes all attacks that dealt pain damage checking siemens
coefficient. This makes everything but hardsuits and voidsuits stronger
against rubber bullets. Insulated gloves are also no longer immune to
rubber bullets."**_
Hardsuits has siemens 0.1, meaning they took 10% damage from all stuns.
Now rubber bullets check their melee armor. Hardsuits are now weaker, or
the same against stuns.
Regular armor all has siemens 0.5, they took a flat 50% reduction.
Security armour is slightly weaker to rubbers, ablative and ballistic
are much weaker. Combat armour is roughly the same, or slightly better.
Riot armour is a lot better.
Voidsuits all had better siemens than armour, all voidsuits are now
weaker against stuns.
Finally, all jumpsuits had 0.75 siemens, but no (or nearly no) armor.
Combined with the fix of them hitting twice this means that rubber
bullets previously dealt 50% more damage against people in jumpsuits
than they do now.
**_- bugfix: "Fixes pain failing to make your blurt out whatever you
were typing. Now getting shot will cause you to say whatever was in the
typing window when you were hit and close the window immediately,
allowing you to move."_**
No more getting stuck in the typing window when you're getting sprayed
down by an STS!
_**- bugfix: "Fixes all attacks that had manually set armour checks,
previously they ignored the armour they were meant to check and decided
what armour affected them based only on their damage type."**_
Weapons that were set to specifically target armour types, such as
explosive projectiles (rockets, etc) were instead defaulting to the
damage type they dealt. So a rocket to the head was checking your melee
armour, not your bomb armour.
---------
Signed-off-by: FenodyreeAv <fenodyree.av@gmail.com>
Integrated circuits support being worn by mobs now!
Lets the circuits that previously said their clips were decorative
actually be worn.
Also lets small ICs be put in the helmet slot, for expeditionary helmet
cameras.
<img width="119" height="111" alt="image"
src="https://github.com/user-attachments/assets/07b1f108-be8d-403d-975f-080ad3a10838"
/>
Hopefully getting a go-pro like sprite for it soon.
Yeah so I did all but the actual important information on how much
phoron and steel that is held in the printer, woops that's my bad. Fixed
that.
Also added mechanical hints to the examine menu on the electronic radio
headset.
Now with fuel tanks being persistent and
https://github.com/Aurorastation/Aurora.3/pull/23027 making the welding
packs start empty, machinists need a way to get welding fuel. As the
fuel tanks from ops are locked to engineering, it is creating a barrier
for them to get it. Hence the removal of the access restriction.
The old earth accent tag did not fit the format of all the other tags -
the placement of the letters and the image (which was far, far too
small) were both wrong. Once you saw it, you couldn't unsee it.
This updates the accent tag with a new and I hope to say much prettier
one. The sun sets over earth - which may be a bit on the nose with NBT2
but there you go.
<img width="225" height="88" alt="image"
src="https://github.com/user-attachments/assets/a034c7ad-023f-4e30-9d14-d752895fe12d"
/>
All sprites by me.
---------
Signed-off-by: Fyni <itsfyni@gmail.com>
-Adds the new Idris Delights vending machine and the various treats sold
within it
-Adds multiple new kitchen dishes (French toast, Lava cakes, Tiramisu,
and Takoyaki)
---------
Signed-off-by: tomixcomics <11053204+tomixcomics@users.noreply.github.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
-Adds Psiren cuisine
-Changes Psirens a bit to better fit cuisine purposes
-Adds a line of code to make sure the game doesn't freeze if flavors
don't get listed correctly for some reason
-Fixes the nutriment amount of Citrus Delight (I forgot to do that in
the generic food update)
---------
Signed-off-by: tomixcomics <11053204+tomixcomics@users.noreply.github.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
* Added the option to manually change the looping sound channel volume
in the SFX Preferences tab.
AI usage disclosure: The code for this was created in-part using GPT 5.6
Sol.
---------
Signed-off-by: Geeves <22774890+Geevies@users.noreply.github.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
```
changes:
- rscadd: "Overmap sector list `initial_generic_waypoints` is now optional."
- refactor: "Small refactor of landmarks and docking markers on the SCC Scout Ship."
```
The `initial_generic_waypoints` could maybe be removed from all maps in
the future, but I didn't want a giga huge diff on this PR.
---------
Co-authored-by: DreamySkrell <>
Also generalizes autolathe recycling so that other containers can alt
click it to be recycled. Currently its still only circuits and the part
exchanger.
changes:
- qol: "Integrated circuit assemblies can now be recycled in autolathes.
They can't be recycled in the printer, because clicking the printer with
the circuit is required to scan it for cloning."
- qol: "Integrated circuits can now be charged in rechargers."
https://github.com/user-attachments/assets/1b8325a8-aca0-4df0-a2a3-763eb8cec989
By modifying power cell capacities,
https://github.com/Aurorastation/Aurora.3/pull/21285 inadvertently
tripled the amount of power available to IPCs in their roundstart power
core, going from 20000 --> 60000. This drags that down to 30000 with a
high-capacity power cell, still half again higher than the original
value, and increases the efficiency of recharge stations a little so
sitting in them is less tedious.
Tiny change, duffel bags can now be accessed in your hands as well as
while on the floor. They still cannot be accessed while on your back.
You still have to sacrifice a hand slot to use duffels, it just removes
some of the busywork involved in dropping it (and makes them more
useable during vents now that your own bag won't run away from you with
the moving air).
---------
Signed-off-by: hazelrat <83198434+hazelrat@users.noreply.github.com>
Co-authored-by: Kano <89972582+kano-dot@users.noreply.github.com>
Adds a new `do_after` flag for progress bar placement. Previously it was
placing the bar on `target` if it was provided in the arguments
(required by do_unique flags), with this flag we're now able to put the
bar on the user
This particular change fixes deployable kits not showing a progress bar.
Also documented some flags on the way