Commit Graph

851 Commits

Author SHA1 Message Date
LemonInTheDark 546dc7fdfa Quarters camera chunk area, Implements better yielding to subsystem on update. (#94530)
## About The Pull Request

[cameras should actually show all of their
view](https://github.com/tgstation/tgstation/commit/a8ef0f3bd7f16e590b9fae193f645c6cb6255f8f)

Melb fucked up luminosity a bit (cries)

[Implements camera range as the deciding factor for who can see a
chunk](https://github.com/tgstation/tgstation/commit/bf4f9776dfce1c15e756ae1933a96ff0cff2dbf0)

This allows us to safely modify chunk size (which I do, down to 8, which
increases the actual cost involved in doing a full z update, but
decreases the cost per chunk significantly)

I use the range to macro optimize chunk New, we can safely use a
bounding box instead of multiple urange calls and get about 1/3 the
performance hit, even with a lower range (and thus 4x as many chunks)

Standard caching and such applies

[Fixes cameras not looking down
correctly](https://github.com/tgstation/tgstation/commit/99b23f25203f34f04c0f92bb7d191699b91a439a)

[Implements yielding support for individual
chunks](https://github.com/tgstation/tgstation/commit/bdd2d01106465b8498307c16f83e9dd90706652a)

This should functionally remove lagspikes from the cameras subsystem,
which just leaves the problem of ais flying around.

Much better tick obedience:


https://github.com/user-attachments/assets/607d61a4-ad96-450c-acdf-10da967ab49b

I tested this pr with #94522 to confirm that halving chunk sizes would
have a benefit, see below:

<img width="364" height="176" alt="image"
src="https://github.com/user-attachments/assets/19f3ae7f-408b-4da5-8e38-a691030138fe"
/>
<img width="462" height="195" alt="image"
src="https://github.com/user-attachments/assets/492b93bf-93ae-4227-9c6d-c5b2f0be9711"
/>
<img width="469" height="229" alt="image"
src="https://github.com/user-attachments/assets/dba92982-09e4-4c3a-96e2-15e1a299676b"
/>
<img width="444" height="233" alt="image"
src="https://github.com/user-attachments/assets/40b1e0dc-c03a-4acd-bba9-f1e4c68bffad"
/>

Things to note:
Mean cost of finding turfs goes from 2ms to 1ms
Max cost of finding turfs goes down by somewhere between 30% and 50%.

I'd call this worthwhile, even if total cost of updating has gone up
slightly.

[Properly manages the camera refs in
chunks](https://github.com/tgstation/tgstation/pull/94530/commits/00c97183ca83a91d95b9afcde70814c36a8f9a5e)

[00c9718](https://github.com/tgstation/tgstation/pull/94530/commits/00c97183ca83a91d95b9afcde70814c36a8f9a5e)

Turns out our solution for moving cameras in chunk code was to just...
NOT CARE!! This means any moving camera is going to cause hard deletes.

This was an issue during unit tests because of a stripping unit test. I
suspect it only showed up here because I reduced the chunk size so we
actually enter/leave a new set of chunks.

I fixed this by reworking things to use a "leaving/joining" pattern.

There's some other stuff here, mostly cleaning up old copypasta'd cruft
in the code adjacent to moving cameras. I also changed the cameras and
processing cameras alists back into lists, mostly for the sake of vv
ability this didn't actually break anything.

The harddel wasn't showing up because it was a number keyed alist, and
reference tracking isn't built to find those (yet, pr up)

## Why It's Good For The Game

I want AIs flying around to not cause massive lag spikes. That + the
camera subsystem are one of like 4 things that's causing reliable tidi
on live and it makes me upset.

## Changelog
🆑
fix: Cameras should work a little better (won't fail in the dark, will
display multiz correctly
refactor: Changed how static turf generation thinks about cameras.
Shouldn't break anything but it MIGHT so keep an eye out for that. The
chunks we use to divvy up the world for them are also 1/4th the area
now, which should make flying around as ai less lagsikey
/🆑

---------

Co-authored-by: Lucy <lucy@absolucy.moe>
2026-02-20 20:58:39 -05:00
SmArtKar f58b8511f0 Refactors effect_system (#94999)
## About The Pull Request

This PR refactors ``effect_system``s to be a bit easier to use by
getting rid of ``set_up``, allowing ``attach()`` to be chained into
``start()`` and refactoring most direct system usages in our code to use
helper procs.

``set_up`` was unnecessary and only existed to allow ``New``'s behavior
to be fully overriden, which is not required if we split
sparks/lightning/steam into a new ``/datum/effect_system/basic`` subtype
which houses the effect spreading behavior. This allows us to roll all
logic from ``set_up`` into ``New`` and cut down on code complexity.
Chaining setup as ``system.attach(src).start()`` also helps a bit in
case no helper method exists

I've added ``do_chem_smoke`` and ``do_foam`` helpers, which respectively
allow chemical smoke or foam to be spawned easily without having to
manually create effect datums and reagent holders.

Also turns out we've had some nonfunctional effect systems which either
never set themselves up, or never started, so I fixed those while I was
at it (mostly by moving them to aforementioned helper procs)

## Why It's Good For The Game

Cleaner code, makes it significantly easier for users to work with. Also
most of our effect system usage was copypasta which was passing booleans
as numbers, while perfectly fine helper procs existed in our code.

## Changelog
🆑
refactor: Refactored sparks, foam, smoke, and other miscellaneous effect
systems.
refactor: Vapes now have consistent rigging with cigs using the new
system.
fix: Fixed some effects never working.
/🆑
2026-02-03 22:23:09 -05:00
Mothblocks eeedcc9414 Respond properly to null SSjob.get_department_type (#95048)
`get_department_type` can return null if all jobs in that department are
disabled. This can't happen in normal gameplay, but is being triggered
in event-base, which disables everything except assistant and cyborg.

This appears to be an expected invariant as job checks it within itself,
and even part of the department_order console code as well.
2026-01-30 19:57:47 -06:00
RikuTheKiller 8f98047bfe [TM FIRST] Literally just halves the performance cost of cameras (#94522)
## About The Pull Request

Title, I used an alist and some inlined list operation tricks to make
camera chunk updates twice as fast.

The data in the screenshots is from me updating every single camera
chunk on Meta. I did also test on Icebox and it scaled just as well
there as it did on Meta, which means that multi-z doesn't cause any
issues for these changes.

The correct way to compare these costs is to take the total cost, divide
it by the count, and then compare them relatively to see which is
higher/lower and by how much.

Before:
<img width="415" height="306" alt="image"
src="https://github.com/user-attachments/assets/c3be5986-e405-412d-a9e0-cc34014a7dab"
/>

After (combined keys):
The value of "update visible turfs" here is just a merged version of
"collect turfs" + "the & operator" + "update visible turfs"
<img width="356" height="271" alt="image"
src="https://github.com/user-attachments/assets/93ca0e9a-bf17-4b87-a4f0-c70c70148ab0"
/>

After 2 (separate keys, but fucked up counts):
Not as directly comparable cuz the counts are fucked up, gotta do some
math to figure it out.
<img width="414" height="293" alt="image"
src="https://github.com/user-attachments/assets/205d4842-4294-4130-a7dd-69d196d318e9"
/>

The biggest remaining performance bottleneck, which now accounts for
~70% of all the performance cost of camera chunks, is camera.can_see()
being slow as balls. You can see this in the After 2 image.

The only cost of doing this is that the format of the list is now
"alist[turf] = null" instead of "list[i] = turf", which makes checking
for individual turfs cumbersome. Entirely possible and and still
relatively performant, but the syntax is just cumbersome. Said single
checks are only used by SyndEye as of now.
## Why It's Good For The Game

On live, it seems that camera chunks are consistently the biggest and
fattest source of performance loss and overtime in the entire game.
Obviously halving that cost is good for the game.
## Changelog
🆑
fix: Camera chunks, the biggest source of lag in the entire game, now
run twice as fast.
/🆑
2026-01-16 17:18:41 -05:00
Ghom 8c534a521e Maintenance PDA themes are added to roundstart PDAs on future rounds as well once installed (#92983)
## About The Pull Request
I'm making the ordeal of finding a maint disk (or buying blackmarket
bootleg disk) with a theme in it a slightly more rewarding experience,
while sticking to the concept that it's something you've to find, unlike
default PDA themes.

This PR also proves to be an opportunity to put the progress tab that I
coded a year ago for the 'Fishdex' to good use.

TODO:
~~Refactor preferences to allow specific choices to be shown/hidden
depending on whether the player meets a defined criteria, otherwise
you'll have to do it manually every round, which is lame~~

- [x] Make some simple ui icons associated with each unlockable theme to
be shown in the cheevo progress tab

- [x] Code to validate deserialized DB values, in the remote case that
any theme is removed in the future, as well as unit test code for any
non-abstract theme without ID

- [x] Add sound cue and chat feedback when unlocking a theme (or when
fishing a new kind of fish for the first time, like, the code's similar)

- [x] Test all of this

## Why It's Good For The Game
These themes are basically an end in itself, and I understand the reason
behind their existence is to make for some cute, little maint loot, but
relegating it to chance of finding a disk somewhere in maintenance,
**every single round** really rots whatever little substance this purely
cosmetic feature already has.

## Changelog

🆑
add: Once installed, special PDA themes from maintenance disks will be
present on your roundstart PDA on future rounds (Sadly I couldn't figure
out a way to add those to the preferences UI yet). You can check which
PDA themes you've unlocked in the Progress tab of the achievements UI.
/🆑
2026-01-16 17:18:03 -05:00
John Willard aedc5bae7a allowed is now signals based instead of hardcoded slots (#94871)
## About The Pull Request

ID cards/MMI mech access/simple mob access/pAIs now use signals instead
of checking specific slots with mob checks. We do this through mob's
``get_access`` proc that collects all access a mob has with a
collect_access signal.

## Why It's Good For The Game

It looks cleaner and we no longer individually check `check_access` for
every single item that may have access. It's cleaner to put it all
together and check in one go with all the access we've got. This also
makes it easier to add items that hold access that aren't necessarily
IDs but you want to be able to open stuff with.

## Changelog

🆑
refactor: ID checking for access has been reworked, please make a bug
report if anything that's supposed to grant access is not working.
/🆑

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
2026-01-16 14:16:22 -07:00
John Willard e86c89edb7 fixes ringing (#94853)
## About The Pull Request

Before
<img width="480" height="29" alt="image"
src="https://github.com/user-attachments/assets/dd352495-c566-481f-aee0-aa8618df7e7e"
/>

After
<img width="496" height="43" alt="image"
src="https://github.com/user-attachments/assets/a0edd64f-50ae-4b7a-8932-292acdd558df"
/>

## Why It's Good For The Game

*ring
2026-01-13 20:45:20 -06:00
Roxy e8a6ac0eec Gives deconstructing modular computers with a wrench a doafter (#94814)
## About The Pull Request
Title. They didn't have a doafter. You could instantly delete shit like
any modular computer and PDAs.

## Why It's Good For The Game
I'd rather not accidentally deconstruct my PDA again. Or any other
modular computer really.

## Changelog

🆑
fix: Modular computers now have a 2 second delay before being
deconstructed.
/🆑
2026-01-11 15:03:39 -05:00
MrMelbert b804e1df79 Revamps security bounties (#94545)
## About The Pull Request

<img width="565" height="201" alt="image"
src="https://github.com/user-attachments/assets/f747992c-82d7-4cd2-9d5c-b94b7de37cdd"
/>

<img width="618" height="108" alt="image"
src="https://github.com/user-attachments/assets/8d5c4e25-87ea-4e53-b9e6-e95e26b3e69f"
/>

- N-spect scanners can no longer print reports

- Clown N-spect scanners have been removed as printing reports was their
primary function

- Security no longer get bounties to loot the brig's equipment. The
contraband bounty is still available.

- Patrol bounties have been reworked. 
- A patrol bounty will give you an area and a number of steps that you
must take in an area.
- To complete the bounty, you must walk to the area and take that many
steps. It's that simple.
   - Your ID card will update you as you progress the bounty. 
- You are rewarded more for larger areas, and less for teeny tiny areas.
- Walking back and forth the same two tiles will not count towards
progress.
- When done, all you need to do is go back to the civ console and press
"send". You don't need to add any items to the pad.
- All security officers can get general patrol bounties (service + maint
+ hallways). Departmental officers can get patrol bounties for their
department.
- And yes, it tracks if your *id card* moves. This means you can strap
your ID card to a drone and it'll count. Get creative if you're lazy.

- ID trims how handle bounty generation. This changes very little,
besides allowing certain trims for certain jobs to add specific
bounties.

- There's now setters for bounties and bank accounts. 

- Fix Bountious Bounty trait by having a `get_reward`

## Why It's Good For The Game

Sec bounties to loot a bunch of miscellaneous things from the brig is...
odd. All it does is deprive your team of equipment should you need it.

On the other hand, patrol bounties are really flavorful, but a bit
cumbersome thanks to needing a hand scanner. By integrating the process
of patrolling *into* the officer's ID card, it means you can just grab a
bounty and go about your business.

The idea is that this'll streamline the process of patrolling a bit and
make it more natural and fun (well, as fun as "walking around" can be.
Which is fun to me...)

## Changelog

🆑 Melbert
del: N-spect scanners can no longer print reports. All it does now is
scan for contraband.
del: Clown N-spect scanners have been removed.
del: Security no longer get bounties to loot the brig's equipment.
Though the contraband bounty is still available.
add: Security's patrol bounties have been reworked. Now, they just
require you to walk around an area for a bit. No scanning necessary.
refactor: Adds setters for bounties and bank accounts. Report any
situations where your bank account is not set correctly.
refactor: ID trims now handle bounty generation. Report any situations
where you get a weird pool of bounties.
fix: Bountious Bounties station trait works again
/🆑
2026-01-11 14:20:11 -05:00
SmArtKar 0f2a1dd6a3 Adds raptor growth progress bar to RaptorDex (#94659)
## About The Pull Request
Players can now check their chick's/youngling's growth progress via the
RaptorDex item or app

## Why It's Good For The Game

Currently there's no way to know how much food you need to feed to your
raptor to advance their growth, which can cause confusion among newer
players.

## Changelog
🆑
qol: Added raptor growth progress bar to RaptorDex
/🆑
2026-01-04 11:44:51 -07:00
Ghom e3c82da770 The Themeify PDA app no longer has an empty checkbox in its options. (#94691)
## About The Pull Request
The imported themes list was made lazy, but by adding null to a list,
you end up having a new key in that list that is null.

## Why It's Good For The Game
Fixing stuff that ArcaneMusic told me about on Discord.

## Changelog

🆑
fix: The Themeify PDA app no longer has an empty checkbox in its
options.
/🆑
2026-01-04 11:44:02 -07:00
mcbalaam 3799968eb3 feat: new floppy disk sprites; most disks are now under the /item/disk type; adds disk stacking, uqinue styling and wrapping (#94112)
## About The Pull Request

Floppy disks received a sprite upgrade, as well as unique wraps:

<img width="364" height="150" alt="image"
src="https://github.com/user-attachments/assets/0ac433e3-7432-4c06-bec2-aeae00b6852f"
/>

<img width="786" height="527" alt="image"
src="https://github.com/user-attachments/assets/0f36bd0d-0362-4431-8131-49060a2fe348"
/>

You can now stack floppy disks! They also scatter around when thrown.
The video also showcases new styling options with a selection of
stickers! You can also write something on the disk instead of selecting
an icon:


https://github.com/user-attachments/assets/ff0a8542-9d79-4108-ae46-672ca5d620a2

MOST disks now inherit the `/item/disk` type to properly stack and do...
stuff. An updatepaths script included.

## Why It's Good For The Game

Old school is cool. Stacking disks makes them feel more authentic, while
styling allows for more crearivity!

## Changelog

🆑
add: New unique wraps for floppy disks
qol: Floppy disks can now be stacked
image: New sprites and stickers for floppy disks
map: Added and ran an updatepaths script
refactor: Most disks are now under the base disk item type
/🆑

---------

Co-authored-by: The-Tyrant <tyrantofgaming@gmail.com>
2026-01-04 08:52:18 +13:00
Roxy 1eac3967a1 Fix cargo PDA app missing currency name (#94641)
## About The Pull Request

All the prices are just numbers theres no cr at the end

## Why It's Good For The Game

Bug fix

## Changelog
🆑
fix: fixed cargo PDA app missing currency name
/🆑
2025-12-29 21:39:12 -05:00
John Willard 4b849174d0 Messenger no longer force opens its UI (#94628)
## About The Pull Request

By default, ``use_energy`` will take 0 as the amount of energy to use,
turning it into a basic "check if we have power" check, however if we
don't exclude ``check_programs`` arg, and because it doesn't use any
power, it will loop through every PDA app to see if they are able to be
opened while unpowered, and opening those that can operate while powered
(aka the PDA messenger).

This is the case for PDA Messenger, so if you're using any app and get a
PDA message, or you reply to one, it will call ``ring()``, which will
call ``use_energy``, which will swap the PDA app to messenger as if the
PDA has no power. This fixes that.

## Why It's Good For The Game

Closes https://github.com/tgstation/tgstation/issues/76965

## Changelog

🆑
fix: PDA messenger will no longer force itself as your active program
when sending/receiving PDA messages.
/🆑
2025-12-28 22:01:29 -05:00
Bloop 53ed83bb9d Makes some more lists lazy (#94388)
Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
2025-12-28 19:57:42 +01:00
John Willard 41f34c2a86 Adds tgui color picker (#94313)
## About The Pull Request

Ports https://github.com/Monkestation/Monkestation2.0/pull/1231 which is
a port of https://github.com/BeeStation/BeeStation-Hornet/pull/9417
which is a port of https://github.com/omgovich/react-colorful/
Also a port of
https://github.com/effigy-se/effigy/blob/main/tgui/packages/tgui/interfaces/effigy/ColorPickerModal.tsx
for hex color presets

Admin stuff got excluded (pref-like picker, filterrific, get-variables)



https://github.com/user-attachments/assets/7069bef9-81cd-4636-bf68-cbad227ef09e


## Why It's Good For The Game

It's one of the only input areas that still doesn't use TGUI, leaving
darkmode players flashbanged every single time a color selection UI is
opened. This is also just visually great and I think a big upgrade from
byond's.

## Changelog

🆑 omgovich, itsmeow, Absolucy, JohnFulpWillard, jlsnow301, TealSeer,
lessthnthree
add: Color selection panels now use TGUI (If you have TGUI enabled in
settings).
/🆑
2025-12-21 16:18:34 -08:00
MrMelbert bfdb237612 Spooky Scary Supreme Surgery (Rework) (#93697) 2025-12-19 18:42:58 +01:00
leaKsi f5e97b5e52 Fixes 2 infinite credits exploits. (#94523)
## About The Pull Request

What it says in the title. 2 href exploits.

## Changelog
🆑
fix: Fixed 2 infinite credit exploits.
/🆑
2025-12-18 09:15:01 -05:00
FalloutFalcon d25c6201f4 Standerdizing currency symbols Part 2 (#94259)
## About The Pull Request
Converts almost all non-constant, non-tgui usages of all variantions of
"credit" and "cr"

Everything seems in order, tested most the currencies.
<img width="905" height="119" alt="image"
src="https://github.com/user-attachments/assets/3fa005a7-a114-426c-9646-b81f68bc2dec"
/>
<img width="255" height="128" alt="image"
src="https://github.com/user-attachments/assets/14c83b54-4fd9-4bee-838f-5b1c03939d9a"
/>


## Why It's Good For The Game
Same justification as https://github.com/tgstation/tgstation/pull/94128
Just easier to mantain/adjust the grammer/names of our money
## Changelog
🆑
spellcheck: minor cleanup on some usecases of "credits"
/🆑
2025-12-13 21:00:19 -05:00
Alien 9175f53a2e Adds "Department Budget" access that lets you place orders with the shopping app, gives it to warden and cargo techs (#94288)
## About The Pull Request

The "NT Shopping Network" app now checks for if you have "Department
Budget" access instead of command access for letting you place orders
and not requests. All heads, cargo techs and the warden have it shift
start but it can be given to anyone (same as EVA access) and heads of
staff can add or remove it at their access consoles.
Also makes warden start with the app to hint that they have access to
the budget.

## Why It's Good For The Game

The access itself is good because letting heads choose who has access to
the department budget is obviously good.
Cargo techs get it cuz they already have access to it by having access
to the request consoles in cargo.
Warden gets it by default because HOS is usually busy
killing/arresting/patrolling while warden is the one actually managing
brig and the armory. If HOS really hates that warden has access to the
budget they can just remove it on their console.
2025-12-11 19:18:37 -06:00
Jacquerel 9fb7c20daa Cargo can buy more presents at Christmas time (#94251)
## About The Pull Request

Last Christmas we had and resolved this bug #88595 where via the
mechanic of buying random trash, Cargo could roll on the roulette to try
and get random Christmas presents and open them for random items.
This was removed because it's not supposed to work that way and was a
way of exploiting Christmas cheer for personal gain, which is grinchsome
behaviour.

That said, being able to order Christmas presents is also kind of
soulful, so this PR brings that mechanic back but on purpose this time.

During the Christmas season _only_, Cargo can spend 3000 credits of
their budget to order a "Surplus Christmas Gifts" crate which contains
4-6 presents _with pre-assigned recipients_.
In a similar system to addressed mail, only the person written on the
gift tag can open the present, so unless you're sufficiently scroogeous
to collect a huge pile of presents on the cargo room floor in hopes of
getting a couple with your name on (in my testing these contained raw
unbaked croissant dough, and a piece of paper from a space ruin) you
should mostly be using this to deliver generalised holiday cheer to the
crew rather than just yourself.



This PR also contains (maybe as more lines than the actual feature) a
refactor changing a bunch of boolean vars on `/datum/supply_pack` into
bitflags, because I needed to add one more and it seemed silly to have
so many booleans.

## Why It's Good For The Game

It allows those with the yuletide spirit to deliver some christmas cheer
to their fellow man, isn't that the season's reason?

## Changelog

🆑
add: When the game considers it to be Christmas, Cargo can order
additional Christmas gifts pre-addressed to random crew members.
/🆑
2025-12-12 02:10:31 +11:00
LT3 1c96273825 Portable crew monitor drag-drop element (#94327) 2025-12-06 16:14:42 -07:00
MrMelbert 9fd5d260c6 Readds Sent from my PDA Sent from my PDA (#94302)
## About The Pull Request

PDA messages once again have a chance to say Sent from my PDA Sent from
my PDA

In the past it was a flat 1% chance going up to 25% chance if you were
over 30. But now I scaled it directly based on age (so the chance can
always go up) Sent from my PDA

## Why It's Good For The Game

I consider this a critical feature Sent from my PDA

## Changelog

🆑 Melbert
add: Readds Sent from my PDA Sent from my PDA
/🆑
2025-12-04 21:03:35 -05:00
Ghom 0b0c5ea91e Unit test material checks are now performed on all crafting recipes by default. All stack recipes now transfer mats to the results (#92620)
## About The Pull Request
Extends the part of the crafting unit test that ensures consistency
between the total mats of the components of a recipe (or rather, the
result of said recipe) and a generic instance of the same type as its
result, previously only implemented on food recipes.

## Why It's Good For The Game
This ensures a degree of consistency with the material composition of
various objects in the game. I couldn't do it in the original PR as that
one was too big already and it took months to get it merged, and have
the relative bugs fixed.

Currently a WIP as I slowly deal with the unit test reports.

## Changelog

🆑
refactor: Follow-up to the crafting/material refactor from months ago.
All objects crafted with stacks now inherit their mat composition (not
necessarily the effects and color) by default, while previously only a
few things like chair, sinks and toilets did. Report any object looking
or behaving weirdly as a result.
fix: The material composition of ammo boxes is no longer a 1/10 of what
it's supposed to be. It was a shitty hack to make it harder to recycle
empty ammo boxes. Instead, they lose materials as they're emptied now.
/🆑
2025-12-02 18:29:01 -05:00
Joshua Kidder 7a3ad79506 All camelCase (Brute|Burn|Fire|Tox|Oxy|Organ|Stamina)(Loss) procs now use snake_case. UNDERSCORES RULE! (#94111)
## About The Pull Request
It's just a partial cleanup of
anti-[STYLE](https://github.com/tgstation/tgstation/blob/master/.github/guides/STYLE.md)
code from /tg/'s ancient history. I compiled & tested with my helpful
assistant and damage is still working.

<img width="1920" height="1040" alt="image"
src="https://github.com/user-attachments/assets/26dabc17-088f-4008-b299-3ff4c27142c3"
/>


I'll upload the .cs script I used to do it shortly.

## Why It's Good For The Game
Just minor code cleanup.

Script used is located at https://metek.tech/camelTo-Snake.7z

EDIT 11/23/25: Updated the script to use multithreading and sequential
scan so it works a hell of a lot faster
```
/*
//
Copyright 2025 Joshua 'Joan Metekillot' Kidder

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
//
*/
using System.Text.RegularExpressions;
class Program
{
    static async Task Main(string[] args)
    {
        var readFile = new FileStreamOptions
        {
            Access = FileAccess.Read,
            Share = FileShare.ReadWrite,
            Options = FileOptions.Asynchronous | FileOptions.SequentialScan
        };
        FileStreamOptions writeFile = new FileStreamOptions
        {
            Share = FileShare.ReadWrite,
            Access = FileAccess.ReadWrite,
            Mode = FileMode.Truncate,
            Options = FileOptions.Asynchronous
        };
        RegexOptions regexOptions = RegexOptions.Multiline | RegexOptions.Compiled;
        Dictionary<string, int> changedProcs = new();
        string regexPattern = @"(?<=\P{L})([a-z]+)([A-Z]{1,2}[a-z]+)*(Brute|Burn|Fire|Tox|Oxy|Organ|Stamina)(Loss)([A-Z]{1,2}[a-z]+)*";
        Regex camelCaseProcRegex = new(regexPattern, regexOptions);

        string snakeify(Match matchingRegex)
        {
            var vals =
            matchingRegex.Groups.Cast<Group>().SelectMany(_ => _.Captures).Select(_ => _.Value).ToArray();
            var newVal = string.Join("_", vals.Skip(1).ToArray()).ToLower();
            string logString = $"{vals[0]} => {newVal}";
            if (changedProcs.TryGetValue(logString, out int value))
            {
                changedProcs[logString] = value + 1;
            }
            else
            {
                changedProcs.Add(logString, 1);
            }
            return newVal;
        }
        var dmFiles = Directory.EnumerateFiles(".", "*.dm", SearchOption.AllDirectories).ToAsyncEnumerable<string>();

        // uses default ParallelOptions
        // https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.paralleloptions?view=net-10.0#main
        await Parallel.ForEachAsync(dmFiles, async (filePath, UnusedCancellationToken) =>
        {
            var reader = new StreamReader(filePath, readFile);
            string oldContent = await reader.ReadToEndAsync();
            string newContent = camelCaseProcRegex.Replace(oldContent, new MatchEvaluator((Func<Match, string>)snakeify));
            if (oldContent != newContent)
            {
                var writer = new StreamWriter(filePath, writeFile);
                await writer.WriteAsync(newContent);
                await writer.DisposeAsync();
            }
            reader.Dispose();
        });
        var logToList = changedProcs.Cast<KeyValuePair<string, int>>().ToList();
        foreach (var pair in logToList)
        {
            Console.WriteLine($"{pair.Key}: {pair.Value} locations");
        }
    }
}

```

## Changelog
🆑 Bisar
code: All (Brute|Burn|Fire|Tox|Oxy|Organ|Stamina)(Loss) procs now use
snake_case, in-line with the STYLE guide. Underscores rule!
/🆑
2025-11-27 15:50:23 -05:00
Bloop 183c5af2e4 Adds flag for virtual areas, fixes being able to send funds from virtualspace to real accounts (#94071)
## About The Pull Request

Fixes https://github.com/tgstation/tgstation/issues/90641
Fixes https://github.com/tgstation/tgstation/issues/88366

Eliminates worries over virtualspace currency being sent to real
accounts.

When I was looking into why there were no flags for bitrunning areas.
Then I saw this mess:

<img width="929" height="889" alt="Code_2we2QjDyFp"
src="https://github.com/user-attachments/assets/8a807bfe-b566-4057-a8ea-2b306325687d"
/>

Not having enough space / being too lazy to refactor this is a silly
reason to not include flags for something like these virtual areas where
it can be quite helpful. Fortunately I am not too lazy ~~in this
moment~~ so here we go:

It was fairly logical to move over some of these to a separate flag,
which I've called `area_flags_mapping` since they pertain to maploading
things and terrain generation mostly. `area_flags` stays reserved for
general properties and now has more room than it did before for you
people to fill it with.

In doing this it's also neatened up the code quit a bit, as UNIQUE_AREA
was kind of everywhere and now that it's implied by default less areas
need to have it defined (or explicitly un-defined).

<details> <summary> Working as intended </summary>

<img width="787" height="448" alt="dreamseeker_p0Qts36tG1"
src="https://github.com/user-attachments/assets/25056f34-8d43-4be2-a293-e53df7a7d1db"
/>

<img width="383" height="59" alt="dreamseeker_Ek7TXCcpbA"
src="https://github.com/user-attachments/assets/89622974-9467-4cdb-8345-d684f7c9004b"
/>

</details>

## Why It's Good For The Game

Fixes an exploit, improves the area flags situation slightly.

## Changelog

🆑
fix: you can no longer send money from virtualspace to a real account
code: adds a flag for virtual areas so they can easily be checked, as
well as an easy helper proc, 'is_area_virtual(your_area)'
/🆑
2025-11-22 12:24:41 -07:00
Fghj240 302b241be2 NT Frontier lets you refund researched nodes (#94074)
## About The Pull Request

If you research a node you can still buy it from NT Frontier, and when
you do it refunds the research points you spent. It's like how
experi-scanners work.

Also cytology gives you an 80 point discount instead of a 120 point
discount. This doesn't change anything because it only costs 80 points
and NT Frontier boosts can't make costs go negative.

## Why It's Good For The Game

Right now it's most efficient to delay research until ordnance gets
finished and then grab all the free stuff, and any head of staff
researching stuff for their own deparment or robo that wants to make
cool mechs can fuck things up. That's not great, because it's
unrealistic to expect everyone to be coordinated and delaying research
never gets tried in practice.

Also, doing ordnance after the round has been going on for a while is
way less effective because all of the nodes you would've discounted were
already researched.

## Changelog
🆑
balance: NT Frontier can purchase and refund researched techweb nodes.
/🆑

---------

Co-authored-by: Fghj240 <fakeemail@notrealemail.com>
2025-11-22 17:29:02 +01:00
John Willard 392dabc356 Fixes some issues with orders showing up as private. (#93986)
## About The Pull Request

Applies the fixes from https://github.com/tgstation/tgstation/pull/93417
to budget ordering console
Also fixes budget ordering improperly setting cargo as the paying
department, as we check for "null" payer to see whether something is
privately paid.

## Why It's Good For The Game

I really hope one of these days this will just get merged so we don't
need this annoying copy paste. How different is the app to the console
anyway?

## Changelog

🆑 SyncIt21, JohnFulpWillard
fix: budget ordering console correctly differentiates between private &
department orders.
fix: budget ordering console checkout cart displays correct
Private/Department order text amounts.
/🆑
2025-11-18 11:03:30 -05:00
MrMelbert 5146cfd403 Moves camera update handling to background subsystem, (maybe) fixing lag (#92208)
## About The Pull Request

When a camera update is triggered, it is instead added to a queue on a
background subsystem

An AI entering a camera chunk which is queued to update will force the
update immediately (bypassing the queue)

While the root problem of this is, ultimately, not addressed...

<img width="554" height="58"
alt="467828777-eff3f0e5-49d6-4997-b4d7-05eff6432155"
src="https://github.com/user-attachments/assets/c2d6a5f5-d958-463e-959f-116bd0dab475"
/>

...the change will ultimately prevent update spam from consuming all of
the server's resources - instead allocating updates to the backburner in
times of high server stress (or on multi-z maps)

## Changelog

🆑 Melbert
refactor: Refactored the way camera updates are handled to hopefully
reduce some lag. Report any oddities
/🆑
2025-11-08 01:43:48 +01:00
Roxy 4c0b617752 Fix PDA RaptorDex being unclosable (#93818)
## About The Pull Request

PDA apps use `<NtosWindow>` instead of `<Window>` because the former
adds a header with an X button and system info, moves all the content of
the RaptorDex component to a new RaptorDexContent component, converts
`<RaptorDex>` to be just the `<Window>` tag and adds a NtosRaptorDex
component for PDAs that uses `<NtosWindow>` instead

## Why It's Good For The Game

Fixes #93761 

## Changelog
🆑
fix: fixed RaptorDex PDA app having no close button
/🆑
2025-11-08 00:36:41 +01:00
tonty 14d2514aa9 [MDB IGNORE] Refactors away /area/station/ai_monitored and its subtypes (with bonus neat repathing) (#93704)
## About The Pull Request

/area/station/ai_monitored's behaviour was isolated into a component,
`/datum/component/monitored_area`, which itself uses
`/datum/motion_group`s to query cameras. Functionally, it (should) work
identically to the old implementation. I'm sure that behaviour could
have been further cleaned up, camera code is quite dreadful, but it's
better to focus on isolating the behaviour first. Baby steps.

Areas that want to opt into monitoring can set `var/motion_monitored` to
TRUE (this approach was taken to make subtyping easier).

The following non-AI areas were changed:
- /area/station/ai_monitored/security/armory ->
/area/station/security/armory
- /area/station/ai_monitored/command/nuke_storage ->
/area/station/command/vault
- /area/station/ai_monitored/command/storage/eva ->
/area/station/command/eva

All other `/area/station/ai_monitored` subtypes were repathed into
`/area/station/ai` and cleaned up in a way that I thought made logical
sense. It is **much** more readable now. For example:

- /area/station/ai_monitored/turret_protected/aisat ->
/area/station/ai/satellite
- /area/station/ai_monitored/command/storage/satellite ->
/area/station/ai/satellite/maintenance/storage
- /area/station/ai_monitored/turret_protected/ai ->
/area/station/ai/satellite/chamber
2025-11-03 11:27:14 -06:00
SmArtKar 1c6c506936 Raptor Rework - Ranching and Companionship (#93564) 2025-11-01 22:13:29 +11:00
OrbisAnima 54cb66c7be [Fix] Corrects exploit that allowed to use departamental budget to buy goodie items (#93668)
## About The Pull Request
Adds a check on wherever its self paid or not when buying stuff as self
paid on the budgetering pda program, so it works like a regular cargo
console

## Why It's Good For The Game
Well, behaviors should be consistent, and this looks more like an
oversight. Its also the only way to order goodies with departamental
budgets atm, and the comments on the goodies flag seem to heavily imply
the intent is for this not to happen.

## Proof of work

### Before

<img width="800" height="506" alt="image"
src="https://github.com/user-attachments/assets/6305531c-0b0e-4a25-bff8-7c20c8a72472"
/>


<img width="901" height="551" alt="image"
src="https://github.com/user-attachments/assets/c45e70a1-be6c-4513-b00a-87f2c098c577"
/>

### After

<img width="924" height="734" alt="image"
src="https://github.com/user-attachments/assets/e9862bf9-5ae7-4945-912c-08c509e18058"
/>

<img width="831" height="616" alt="image"
src="https://github.com/user-attachments/assets/4b66aa64-03cd-4724-913f-2fee5489d09f"
/>


## Changelog
🆑
fix: solves an exploit that allowed users to buy goodie packs with the
pda budget program
/🆑
2025-10-29 16:34:13 +01:00
die 54198986b7 generic device handling sounds (#93536) 2025-10-24 09:42:10 +02:00
SyncIt21 4c930567d8 Fixes pda internal cam app lagging the server (#93509)
- Fixes #93508

Does 2 things
- Makes the operation asynchronous so it does not interfere with the
server
- Ensures we don't click multiple photos while the single photo is still
processing. Displays a balloon alert for the same
2025-10-22 04:55:39 -04:00
SmArtKar 4d648d016c Sleeping Carp and Cain & Abel no longer tell you about armor penetration when you reflect projectiles with them (#93275)
## About The Pull Request

Projectile refactor pulled armor check above the pre-hit comsig, this
fixes that. No need to check armor before you're hit when you
potentially will not be.

## Changelog
🆑
fix: Sleeping Carp and Cain & Abel no longer tell you about armor
penetration when you reflect projectiles with them
/🆑
2025-10-12 05:39:43 +02:00
MrMelbert da10322dc1 Fix modsuits and defibs (#93373)
## About The Pull Request

Fixes #93359

Caused by #93165

Inventory screen elements were no longer considered reachable, which
broke mousedrop handing on objects that check "is dragging into
inventory slot"

I don't know the best way to fix this yet but I figured the next best
thing would be to make all of these use the `drag_pickup` element, which
skips this reach-ability check

Thus I refactored it slightly to accommodate for items which should
contextually not be drag-pick-up-abble and bam, works like a charm

## Changelog

🆑 Melbert
fix: Dragging defibs and modsuits off your back works again
/🆑

---------

Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
Co-authored-by: Xander3359 <66163761+Xander3359@users.noreply.github.com>
2025-10-11 18:17:23 -04:00
ArcaneMusic bf4cc3e415 Cargo requests for other departments may now request they come out of the department budget. (#93152)
## About The Pull Request

When placing a cargo request as a non-cargo staff, you may now specify
which department you are requesting this for, which if approved will
bill that department from their budget. Requests placed this way will
need to be approved by cargo staff by default.

Originally I was going to tie this to my proposed rolling permission
system (Think an email chain where if things don't get approved, it goes
up a PDA Message chain until someone approves the thing), however I've
quite stalled on that and I wanted to at least get the baseline
functionality into people's hands.

Cargo, as per usual, has a right to refusal to reject the request as
well.

<img width="797" height="199" alt="image"
src="https://github.com/user-attachments/assets/19889b0a-8af5-4347-b91a-91cc39ab2bee"
/>
_WIP Photos, names/departments only show here as undefined due to being
admin spawned and not naturally spawned players_

## Why It's Good For The Game

Heads of staff can already order crates using their departmental
ordering apps and utilizing their funds, without needing QM approval.
This will allow for crewmembers within a department to request to
requisition supplies using their budget's funds as well.

As it stands, ordering from budget is already quite clunky, and being
able to go to cargo to place a request for your department should at
least elicit a conversation between heads of staff to see if it makes
sense. Keeping in mind, spending too much of a budget's funds can result
in failure to complete paychecks, so there is some conflict that can
arise from interacting with this mechanic too aggressively.

**I'll be real, there's a pretty good chance this may be too easy to use
and too powerful in it's current state.** If it needs something like the
additional rolling permissions system in place in the future, we may
want to re-assess at a later point.

## Changelog

🆑
qol: When placing cargo requests, you can now request that a crate be
obtained using your department's funds as opposed to the cargo budget.
/🆑

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
2025-10-09 21:16:15 +02:00
Archemagus 6f834fb418 AAS code cleanup (#93158)
## About The Pull Request

- Added full support for RETA system
- Categorized all configs for search purposes
- Added channel check for most usages of get_announcement_system() calls
## Why It's Good For The Game
## Changelog
🆑
code: Little AAS code cleanup. Added full RETA support. Grouped configs
for search purposes.
/🆑
2025-10-02 18:17:38 +00:00
MrMelbert 750ca9d2ec Two as anything greps (and some other cleanup) (#92974) 2025-09-20 13:44:28 -04:00
John Willard 76600a8f52 Adds a new default PDA theme and 3 new maint ones (#92968)
## About The Pull Request

Was looking at tgui core and found some themes that looked cool, so I
added them

New default theme, Bird
<img width="602" height="602" alt="image"
src="https://github.com/user-attachments/assets/5864a50b-efa8-4464-93eb-a124ba651b98"
/>

#### The rest are maint themes

Hackerman
<img width="601" height="598" alt="image"
src="https://github.com/user-attachments/assets/f1e68ace-eaee-4a1b-9574-7705a8d1be18"
/>

Roulette table
<img width="599" height="601" alt="image"
src="https://github.com/user-attachments/assets/12985c4d-a3d8-4f76-b212-d10fb92293c3"
/>

Alien
<img width="604" height="602" alt="image"
src="https://github.com/user-attachments/assets/d8933c03-47b4-4c04-932d-0649d3506c16"
/>

As always these are all available to the clear PDA by default.

## Why It's Good For The Game

They just looked nice, so why not

## Changelog

🆑
add: Added a new PDA theme and 3 secret ones you may find in
maintenance.
/🆑
2025-09-14 14:06:42 +02:00
Ghom c4f99f9370 The art gallery app can now be downloaded on PDAs and laptops (no printing) (#92615) 2025-08-26 22:53:55 -06:00
Lucy 5d8bddfcf4 Pre-sort PDA messengers by name/job instead of sorting every time we list them (#92613)
## About The Pull Request

this gets rid of the `get_messengers_sorted_by_name` and
`get_messengers_sorted_by_job` procs, instead replacing them with two
new global lists: `GLOB.pda_messengers_by_name` and
`GLOB.pda_messengers_by_job`

those two lists are updated in the `add_messenger` proc, which uses the
binary insert macros to insert it into the properly sorted place.

why? bc sorts suck for performance and all inserts/removals to this list
go thru a single proc anyways, so we can just ensure it's sorted like
this once, instead of re-sorting each time.

thanks to @LemonInTheDark for helping me with this

<details>
<summary><h3>Testing Proof</h3></summary>

<img width="1708" height="1349" alt="2025-08-16 (1755391989) ~
dreamseeker"
src="https://github.com/user-attachments/assets/1e2dc99a-1863-4a35-8032-8ae64706fdaa"
/>

<img width="1708" height="1349" alt="2025-08-16 (1755392002) ~
dreamseeker"
src="https://github.com/user-attachments/assets/4d9b3bd0-7f3a-410b-a073-1bf2bd69690b"
/>

</details>

## Why It's Good For The Game

because doing a sort repeatedly whenever someone has their PDA messenger
open is stupid and sucks

## Changelog

no player-facing changes
2025-08-18 00:15:18 +02:00
tonyhawq 48fc67f7bb Fixes an issue where called shuttles would say "1 minutes" instead of "1 minute" (#92539)
## About The Pull Request
<img width="397" height="190" alt="image"
src="https://github.com/user-attachments/assets/41e915bc-6d8c-4180-83f1-12380c76554c"
/>

<img width="220" height="112" alt="image"
src="https://github.com/user-attachments/assets/ef3aa542-e6e3-4983-8917-66009d4f843e"
/>

## Why It's Good For The Game
It. is good 👍 

## Changelog

🆑
spellcheck: shuttles will now say "arriving in 1 minute" instead of "1
minutes"
/🆑
2025-08-15 04:22:08 +02:00
MrMelbert f1234ac5d0 Fix master skew (#92568)
Yippee
2025-08-14 11:03:33 +12:00
plsleavemealon 574595529f bounty app for PDA (#91802)
## About The Pull Request

This PR adds a brand new app to the PDA allowing you to view your
current bounties and even generate new ones.

You can even select a bounty remotely and it will seemlessly work.

The program is not without its own drawbacks. Choosing to reroll your
bounties from the app will always trigger a 5 minute cooldown, and this
cannot be reduced. Meaning that rerolling directly from the bounty
terminal (assuming it has been upgraded) is preferable as an upgraded
bounty pad will give the terminal a shorter cooldown. The cooldown is
shared between the app and the terminal, and depends on where you
initially rerolled it. So if you rerolled it from the app, it will
always be 5 minutes, but if you rerolled it from the terminal, it may be
as low as 2 minutes.

Otherwise it is identical to the way the bounty terminal functions,
minus the fact you cannot actually turn in the bounty using your PDA,
you still have to go to a terminal with connected bounty pad for that!

And in addition to that, in order for the app to work you must have your
ID inside your PDA, the app will not function without it (the top button
will be greyed out, and trying to push one of the options will just give
you a minor error sound)

Size is 5 GQ since that seemed like a good enough size for it.

## Why It's Good For The Game

It always annoyed me that I had to run all the way back to cargo to
check on what my bounties are, and this solves that. It also lets you
reroll your bounties remotely with a punishment of it always having the
default (5 min) waiting period between rerolls.

## Changelog

🆑
add: Adds a new bounty app to the PDA allowing you to remotely check
your bounties
/🆑

![image](https://github.com/user-attachments/assets/b0a10106-1c6d-4f9e-91b1-f95f8cc377cb)

![image](https://github.com/user-attachments/assets/c2cc8075-7314-48b1-a668-e7f8a44bc217)

![image](https://github.com/user-attachments/assets/9536b8cb-8c95-47ed-ba42-2a8d162123c7)

![image](https://github.com/user-attachments/assets/eb254331-35f0-413a-9b74-77c5f9ad6ccb)

---------

Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
2025-08-13 15:08:48 -04:00
_0Steven 69bd91b2f4 Fixes newscaster channels having a random chance of breaking upon creation of a new channel, refactors how channels are tracked in the first place (#92371)
## About The Pull Request

So in a recent round I noticed the newscaster UI was acting kind of
funky, where two channels seemed to overlap and weirdly pick between the
two in unpredictable ways. Looking into it, it seemed that somehow the
channels had managed to get their unique IDs to overlap-
Oh.

https://github.com/tgstation/tgstation/blob/5d3353e7af2b88ab9379d5fb567b24afd8776acd/code/game/machinery/newscaster/newscaster_data.dm#L109-L131
I see.

...I think that code speaks for itself, in how this could've gone wrong.

Anyhow, in this pr we entirely ditch this system, and instead make it
use an incremental and thus guaranteed to be unique ID.
This fixes our issues.

While we're here, we also remove the unused `channel_IDs` list, and
replace it with the associative lists `network_channels_by_id` and
`network_channels_by_name`. This allows us to also stop iterating over
every network channel until we find the one with the right name or ID.
We also rename some confusing, wrong, or non-standard vars while we're
here.
2025-08-12 16:22:35 -05:00
MrMelbert 5df4de3f71 [MDB Ignore] Re-add hop console second ID slot (#92157)
## About The Pull Request

<img width="491" height="301" alt="image"
src="https://github.com/user-attachments/assets/a3b5b19f-edf5-4de9-9201-9cbfab9e8827"
/>

Mod computers with the access changing software installed have a
secondary ID slot once again. This ID slot doesn't contribute to access.
You can insert IDs into the slot with right click and remove them with
alt-right click.

Also removes the "New IDs and you" memo paper. 

Also tweaks PDA on_deconstruct so contents are dropped on when they're
deconstructed with assembly.

Fixes #92151

## Why It's Good For The Game

Changing IDs is very unnecessarily clunky with the one slot. Insert hop
id, log in, remove hop id, insert crew id, change access, remove crew
id, log out.

We had it right back when we had two slots. Insert hop ID, insert crew
id, log in. It just works.

This also allows for mobile HoPs to change access without necessitating
removing their ID from their PDA.

Other changes: 

The "New IDs and you" memo is very old. They haven't been new for 4
years now. I don't think anyone reads it and they served their purpose.

I found it odd that, if your PDA was melted or blown up, it would delete
your ID. If this is a hold-over from old PDA behavior feel free to let
me know but otherwise it seems sensible that it'd spit out the contents
as you would expect.

## Changelog

🆑 Melbert
qol: The access changing software (the HoP console) now has ID two slots
again (one for the HoP's id and one for the ID being changed). You can
insert IDs in the secondary slot via the UI or right click, and remove
them via the UI or alt-right click.
qol: If your PDA is destroyed via acid or bombs, your ID (and similar
contents such as disks) are spit out instead of being deleted
del: Deletes the "New IDs and you" memo in the HoP's office. They
haven't been new for 4 years.
fix: Engineering sub-tab in the access changing software no longer looks
messed up
fix: Fix reversed alt-click logic for mod pcs
/🆑
2025-08-11 19:08:18 +00:00
SSensum13 4722bf017e Some ITEM_SLOT bitflags fixes. (#92441)
## About The Pull Request

This PR fixes wrong usage of bitflags in a few places, where instead of
bitfields lists were used.

## Why It's Good For The Game

It will help prevent problems that can be a thing in the future,
improving consistency of the codebase.
2025-08-11 13:20:50 -05:00
SyncIt21 0b6101a37e General maintenance for vending machines (#91987)
## About The Pull Request
**1. Code Improvements**
- Removed unused vars `coin`, `bill` & other stuff
- Removed duplicate definition of `on_deconstruction()`
- Autodoc for a lot of procs
- Merged smaller procs into larger ones to avoid scrolling in the code
editor & reduced overhead
- Split the vending machine file into several smaller files for easy
code management

**2. Qol**
- Implemented vending machine ads. They now display random stuff on the
UI


https://github.com/user-attachments/assets/9720ea60-f268-4ca2-940d-243e3d0ac75f
- More error messages for custom & normal vendors as to why an item
could not be loaded
- Custom vending machines can be deconstructed safely via crowbar
without any explosion only after unlinking your account from the machine
else you get the same explosion. Upon deconstruction all loaded items
are moved into its restock canister meaning the machine can be safely
moved with all its products just like a regular vending machine to a new
location

**3. Fixes**
- Fixes #81917. Any returned items in the vending machine now show up as
free in the UI & won't cost credits to buy them
- Fixes #87416. Custom & normal vendors now keep track of products
removed via `Exited()` so the UI gets always updated
- Fixes #83151. Items with different names & custom prices now show up
in unique rows
- Fixes #92170 Custom vendors now show the correct icon for inserted
items
- Closes #80010. From the above fix this situation is impossible so it's
safe to close this as a duplicate
- Closes #78016 same problem as above with `Exited()` duplicate
- Custom vendors can now actually be used by players who are not the
owner instead of locking down the UI
- Vending machines keep track of `max_amount` of stocked items by hand
as well & not just RPED

**4. Refactor**
- Separates custom vending machine code from normal vending machine
code. This prime Marely focus on the `vending_machine_input` list which
now only exists inside the custom vending machine
- Compressed the UI code for vending machine so both custom & normal
vending machines can send the same data instead of separating the 2.
Overall less code
- Moved attack chain from `attackby()` to `item_interaction()` for
loading items

## Changelog
🆑
code: cleaned up vending machine code
qol: vending machines now have more product slogans you never heard
before
qol: custom & normal vending machines now have more feedback on why an
item could not be loaded
qol: vending machines now display random ads on the UI
qol: custom vending machines can be deconstructed via crowbar safely
only after unlinking your account from the machine.
qol: upon deconstructing a custom vendor all its products are moved into
its refill canister & it will be restored when reconstructing the
machine elsewhere
fix: Returned items to the vending machine now show up as free in the UI
and won't be greyed out if you don't have credits to get them back
fix: items that leave the vending machine by any means will update the
UI in all cases
fix: loading items by hand to the vending machine now respects the
max_amount for that category
fix: custom vendors can now actually be used by players who are not the
owner thus enabling them to transfer credits to the owner during
purchases & basically they do their job again
fix: custom vendors now show the correct icon for inserted items
fix: Items with different names & custom prices now show up in unique
rows in custom vendors
refactor: separated custom & normal vending machine code. Reduced UI
code & improved attack chain
/🆑

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
2025-08-11 14:37:13 +02:00