* Cleans up some varedit procs not using strings instead of the proper helper (#65769)
Although these vars are unlikely to ever change, if the vars were ever renamed it would result in these strings not erroring properly if they weren't updated as well.
* Cleans up some varedit procs using strings for var names instead of the proper helper
Co-authored-by: ShizCalev <ShizCalev@users.noreply.github.com>
* makes vent scrubbers only activate if a gas they filter is on their tile, again! alive edition (#65591)
Alsonce scrubbers only wake up if something they can filter is on the tile an existing bug where scrubbers dont filter very small but non garbage collectable amounts of a gas becomes a big issue, as in without changing scrubbing rates you can breathe once on a tile with a scrubber set to scrub co2 and that co2 wont go away barring any other factors and the scrubber wont go to sleep. so now with the idea of rohesie and permission of lemon i changed how scrubbers removed small molar amounts of gas from their turf. now scrubbers will look through 100% of the turfs air mix for filtering, but will only remove up to
gas moles * (scrubber volume / turf volume) * (gas moles / total filterable moles) moles from each filterable gas in the turfs mix unless that amount is less than either MOLAR_ACCURACY * 100 or the number of moles of that filterable gas, in which case all of the moles of that gas are subtracted from the mix. this is to make it easier for the scrubber to remove very small amounts of gas with filters without changing how fast they scrub large amounts of gas, thus making scrubbers able to go to sleep faster only after a gas has been reduced to near zero
scrubbers are the biggest proportion of SSair's machine processing cost which is a non trivial amount of SSair's total cost. now they will only do most of their work if they can actually scrub anything on the tile which is a minority of the time.
* makes vent scrubbers only activate if a gas they filter is on their tile, again! alive edition
Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
* Arconomy Adjacent Content: Newscaster Refactor Omega
* Fixed all of the issues that resulted from the repathing
* Fixed our modularized priority_announce.dm
* Deleted newscaster.dm because it was still there due to two comments that weren't overly important
* Fixed merge conflicts for delta
* Fixed a bunch of skyrat maps so they compile :)
* I forgor a few more maps
* Add newscaster_bounty for our newscaster sprite (#12344)
Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
Co-authored-by: Tastyfish <crazychris32@gmail.com>
* Becoming the patron of a painting now lets you select a different, persistent appearance for the frame it's in. (#65305)
* Painting frame selection for patrons, painting json version update.
* Becoming the patron of a painting now lets you select a different, persistent appearance for the frame it's in.
* fix unit test
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
Co-authored-by: John Doe <gamingskeleton3@gmail.com>
* Improved the Art Gallery App and the AI Portrait Picker. Added a search function to them. (#65481)
* Improved the Art Gallery App. Added a search function to it.
* Improved the Art Gallery App and the AI Portrait Picker. Added a search function to them.
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
* Fixes persistent painting patron name not being loaded (#65411)
* Fixes persistent painting patron name not being loaded
Co-authored-by: AnturK <AnturK@users.noreply.github.com>
* Restores the Persistent Scars preference (#65358)
* Restores the Persistant Scars preference
I also had to remove some raw READ_FILE()s because that was now useless. I was thus able to remove the persistent_scars variable from the prefs, as it is now a standalone preference.
* I forgor...
* Restores the Persistent Scars preference
Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
* Hardens painting saving against inconsistent state (#65024)
Should help when paintings lists gets zeroed unintentionally during the round for some reason.
Now it only deletes the painting file right before it writes the new file to prevent loss of data if anything runtimes or breaks.
* Hardens painting saving against inconsistent state
Co-authored-by: AnturK <AnturK@users.noreply.github.com>
* Refactor: make SSrunechat to be subsystem of SStimer (#64366)
* Refactor: make SSrunechat to be subsystem of SStimer
Co-authored-by: Aziz Chynaliev <azizonkg@gmail.com>
* Makes SSTimer actually recover (#64784)
Makes SSTimer actually recover properly when it needs to. This is a follow-up for #60846 (3da51f515d) with code I added in my port of that PR to bee.
There were 3 main problems, and each was uncovered after fixing the previous:
/datum/controller/master/New() was using faulty logic to find existing subsystems. It was adding Sound Loops twice and not adding Timer at all (Sound Loops being a subtype of Timer).
/datum/timedevent stores a ref to the timer subsystem in var/datum/controller/subsystem/timer/timer_subsystem for performance. It wasn't being updated to the new Timer subsystem, ultimately resulting in it runtiming as an invalid timer.
The buckets need to be reset during recovery. The TTR and other bucket-related handling is out of whack because SSTimer wasn't firing for however long recovery took. Luckily reset_buckets() can already handle all of this.
* Makes SSTimer actually recover
Co-authored-by: ike709 <ike709@users.noreply.github.com>
* Adds logic to hopefully prevent/yell about init breaking (#64705)
Safeguards restoring initialize mode after runtimes during atom initialization
* Adds logic to hopefully prevent/yell about init breaking
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
* Fix random job assignments occasionally assigning to roles that were already filled (#64734)
Missing continue in the random job assignment code meant an if statement was ineffective, code fell through and assigned roles to jobs that were already full.
* Fix random job assignments occasionally assigning to roles that were already filled.
Co-authored-by: Timberpoes <silent_insomnia_pp@hotmail.co.uk>
* Fixes a potential "fail to setup jobs" state due to disappearing clients (#64735)
Fixes a runtime error that can occur during DivideOccupations() in the event that one of the players has their clients disappear during setup due to classic byond client volatility.
If a new player's client vanishes during job setup, it will read as null instead of runtiming, which throws a JobDebug and moves onto the next player.
* Fixes a potential "fail to setup jobs" state due to disappearing clients
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
* Moves adjacent air into the main atmos subsystem (#64559)
We should just straight up not be processing turfs if the adjacent turf
isn't correctly setup
It used to be on a seperate subsystem with a second wait with the idea
of reducing the cost of explosions, but since they're instant now
there's no reason to not just have it on SSair. Gets rid of my excuse
for process_cell runtimes too
* Moves adjacent air into the main atmos subsystem
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
* Fixes being able to vote for maps which are outside their configured population range (#64619)
* fixes map voting?
* this is worth checking as well
* additional logging
* Fixes being able to vote for maps which are outside their configured population range
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
* Fix stickyban SS runtiming on initialize (#64586)
Stickyban SS no longer runtimes if there is broken entries in the DB and instead notifes admins
* Fix stickyban SS runtiming on initialize
Co-authored-by: Gamer025 <33846895+Gamer025@users.noreply.github.com>
* Black Market code, Revisited. (#64271)
This PR updates and refreshes the whole of black market code for improved usability as well as to better sell the backbone of the content behind the blackmarket in-game.
For starters, the datums for the black market were designed around not being specific to the black market. Reading the code, it was intended to allow for multiple blackmarket_markets to be added after it's original inclusion, which was passed up as a result of what I'd guess is a branding issue, as every datum associated with the blackmarket was labeled... as for the black market, nothing else.
So to begin I've renamed most of the backend of the blackmarket code to just market instead, datum/market, datum/market_order, datum/market_item, datum/market_uplink(/blackmarket). The works.
Next, QOL change to how blackmarket uplinks were implemented: Now, instead of having to manually load credits into a black market uplink by hand, then choose to buy things using the uplink, they instead just draw from the user's ID card, checks for a bank account, and purchases through that, with quick inputs added when purchases are successful and warnings when a purchase cannot be made.
Lastly, code change. In an old economy PR of mine I standardized purchased cargo items to use the CARGO_CRATE_VALUE define, and for vendible items to use paycheck defines instead. In that PR I rebalanced quite a bit of prices as a result, but this got passed up when that happened. I'll leave the balancing for another time then, but this updates the code of market_item datums to use CARGO_CRATE_VALUE for their upper and lower cost ranges to maintain that standard.
* Black Market code, Revisited.
* Black Market code, Revisited.
Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>
* Fixes a few runtimes with armor, spatial grids, and notes (#64514)
* Atoms (mostly new players caused by logout) can get deleted before spatial grid initializes.
* Fixes images when viewing your notes before SSassets initializes.
* Fixes abandoned crate runtime.
* Fixes armor runtimes on eating clothes (this really needs alternative solution)
* Fixes a few runtimes with armor, spatial grids, and notes
Co-authored-by: AnturK <AnturK@users.noreply.github.com>
* Actually fixes strange mob delays: BEEPSKY IS TOO FAST edition (#64351)
* Revert " Properly speeds up a lot of things, mostly mobs (#64270)"
This reverts commit a836574388.
THE BYOND REF WAS A LIE, THE PLAYERS ARE FOOLS, HELP, HELPPPPPPP
It turns out that despite what the byond ref says, the walk proc's delays were not in fact in ticks, but in deciseconds.
This means when I "fixed" mob movement by doubling all walk delays, what I actually did was double the speed of anything that used walk()
I have a feeling that the actual issue players were seeing was just move_to having fucked up distance logic, and the movement of slow mobs being smoothed out. I've changed that, so hopefully this puts a seal on the whole problem
I've had a request put in to make beepsky faster, but I think that's best done in a seperate pr
* Adds a flag to disable smooth moveloop movement
Applies it to hostile mob's Goto()
Backports the fixes to move_to and move_away from the previous pr
* Actually fixes strange mob delays: BEEPSKY IS TOO FAST edition
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
* makes most statpanel tabs update a tenth or so as often (>= 4 seconds instead of 4 deciseconds) because theyre wastful of cpu (#63991)
makes most updating stat panel tabs update once every 4 seconds instead of 4 deciseconds, but switching tabs instantly updates statpanel data for you. also makes examining a turf make flat icons for a maximum of 10 contents instead of 30 because its ridiculous to call getFuckingFlatIcon() wrappers that many times. also makes SSfluids not have SS_TICKER and updates its wait accordingly because theres no reason for it to be a ticker subsystem
the mc tab updates every 2 seconds unless someone has the pref enabled to refresh it quickly because SOME UNILLUMINATED LEMONS absolutely must watch overtime spikes in real time
statpanels can take between 1-3% of masters total processing time at very high pop, which is silly considering theres no need for someone to know any of the data updated accurate to less than half of a second. The only reason it needed to update so fast was because it looked awful when switching tabs, which will only be updated on the next fire. now switching tabs updates data instantly so theres no need to update the rest of the data quickly.
also makes each stat tab update into its own proc so we can tell how much each tab update costs
* makes most statpanel tabs update a tenth or so as often (>= 4 seconds instead of 4 deciseconds) because theyre wastful of cpu
* E
* https://github.com/Skyrat-SS13/Skyrat-tg/pull/11003
Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
* prevents smuggler satchels from spawning where they shouldn't (#64346)
Stops smuggler's satchels from spawning on floor turfs which cannot conceal them, such as catwalks and glass floors.
* prevents smuggler satchels from spawning on catwalks
Co-authored-by: magatsuchi <88991542+magatsuchi@users.noreply.github.com>
* Documents economy and bank account variables. (#64217)
* Documents economy and bank account variables
Co-authored-by: John Willard <53777086+JohnFulpWillard@ users.noreply.github.com>
* Documents economy and bank account variables.
Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
* Fix: Avoid runechat scheduling too far events into short queue (#64322)
Ports fix from SStimer #64242
Why It's Good For The Game
Changelog
cl Semoro
fix: Avoid runechat scheduling too far events into short queue (port from SStimer)
/cl
* Fix: Avoid runechat scheduling too far events into short queue
Co-authored-by: Aziz Chynaliev <azizonkg@gmail.com>
* Fix: Avoid timer scheduling too far events into short queue (#64242)
Previously it was possible for events to enter the short queue when the timer is offset by more than BUCKET_LEN
Now it is forced to schedule events into the second queue if the timer is processing slower then world time goes allowing the timer to keep up
This PR provides a better definition of TIMER_MAX to avoid scheduling timed events that are more than one window of buckets away in terms of timeToRun into buckets queue and properly passing them into the second queue.
Ports ss220-space/Paradise#578
Should be merged with/after #64138
Detailed explanation
The timer subsystem mainly uses two concepts, buckets, and second queue
Buckets is a fixed-length list of linked lists, where each "bucket" contains timers scheduled to run on the same tick
The second queue is a simple list containing sorted timers that scheduled too far in future
To process buckets, the timer uses two variables named head_offset and practical_offset
head_offset determines the offset of the first bucket in time
while practical_offset determines offset from bucket list beginning
There are two equations responsible for determining where timed event would end up scheduled
TIMER_MAX and BUCKET_POS
TIMER_MAX determines the maximum value of timeToRun for timed event to schedule into buckets and not the second queue
While BUCKET_POS determines where to put timed event relative to current head_offset
Let's look at BUCKET_POS first
BUCKET_POS(timer) = (((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag)+1) % BUCKET_LEN)||BUCKET_LEN)
Let's imagine we have our tick_lag set to 0.5, due to that we will have BUCKET_LEN = (10 / 0.5) * 60 = 1200
And head_offset of 100, that would make any timed event with timeToRun = 100 + 600N to get bucket_pos of 1
Now let's look at the current implementation of TIMER_MAX
TIMER_MAX = (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1)))
Let's say our world.time = 100 and practical_offset = 1 for now
So TIMER_MAX = 100 + min(1200 - (1 - (100 - 100)/0.5) - 1, 1200 - 1) * 0.5 = 100 + 1198 * 0.5 = 699
As you might see, in that example we're fine and no events can be scheduled in buckets past boundary
But let's now imagine a situation: some high priority subsystem lagged and caused the timer not to fire for a bit
Now our world.time = 200 and practical_offset = 1 still
So now our TIMER_MAX would be calculated as follow
TIMER_MAX = 200 + min(Q, 1199) * 0.5
Where Q = 1200 - 1 - (1 - (200 - 100) / 0.5) = 1200 - 1 - 1 + (200 - 100) / 0.5 = 1398
Which is bigger then 1199, so we will choose 1199 instead
TIMER_MAX = 200 + 599.5 = 799.5
Let's now schedule repetitive timed event with timeToRun = world.time + 500
It will be scheduled into buckets since, 700 < TIMER_MAX
BUCKET_POS will be ((700 - 100) / 0.5 + 1) % 1200 = 1
Let's run the timer subsystem
During the execution of that timer, we will try to reschedule it for the next fire at timeToRun = world.time + 500
Which would end up adding it in the same bucket we are currently processing, locking subsystem in a loop till suspending
On next tick we will try to continue and will reschedule at timeToRun = world.time + 0.5 + 500
Which would end up in bucket 2, constantly blocking the timer from processing normally
Why It's Good For The Game
Increases chances of smooth experience
Changelog
cl Semoro
fix: Avoid timer scheduling too far events into short queue
/cl
* Fix: Avoid timer scheduling too far events into short queue
Co-authored-by: Aziz Chynaliev <azizonkg@gmail.com>
* Fix: timers not removing from second queue on init (#64138)
Fixes#56292
Why It's Good For The Game
Increases chances of smooth experience
Changelog
cl Semoro
fix: timers not removing from second queue on init
/cl
* Fix: timers not removing from second queue on init
Co-authored-by: Aziz Chynaliev <azizonkg@gmail.com>
* Properly speeds up a lot of things, mostly mobs (#64270)
When I made my move loop changes (815bb8a) 62567, I converted a few walk() procs to
the new system
What I didn't know when I did that conversion is that walk() operates on ticks, when move loops operate on
deciseconds
So when I converted say, mob movement over, I accidentially halved the attack movespeed of all of our mobs
This resolves that, alongside a few other misteps
Of note: There are old comments implying that walk()'s delay is not actually linear, or simply as the reference says "in ticks"
I don't have a good idea of how fast things actually should be though, which makes this tricky
In light of this, I've decreased the move speed of legion slightly, in hopes that it will feel more "normal"
I've also fixed a bug with move_to and move_away, they were treating their distance parameters as move to this and one more, rather then move to this. This lead to mobs attempting to overlap with your sprite. s cringe, and also fixed
* Properly speeds up a lot of things, mostly mobs
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>