[MIRROR] [NO GBP] fixing dynamic [MDB IGNORE] (#23184)

* [NO GBP] fixing dynamic (#77734)

## About The Pull Request
Yeah, the built-in `arctan()` proc actually returns degrees rather than
radians so I had to revert the change to the macro. Also, I had to
revamp the whole formula once again because the old one was eh. The
random location of -0.5 to 0.5 meant it never went lower/higher than the
40-60% threat range, and the RNG deviation was crappy.

As a bonus, I slighly lowered the threat requirements for the wizard's
gun/magic/events rituals, since reaching a full 100 is a smidge less
likely now (previously the odds were one in ten if the threat score was
higher than 90%, now it's a 0.5% chance in total, as the threat is
rounded to intervals of 1).

## Why It's Good For The Game
This will fix #77726.

Here's the updated desmos graph:
https://www.desmos.com/calculator/fpc7gwtwla (the red curve is the one
without the deviation, the black one is with the deviation)

Gimme a few minutes to run one last test, tho. I cannot trust myself too
much.

## Changelog

🆑
fix: Fixed dynamic.
/🆑

* [NO GBP] fixing dynamic

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-08-18 19:24:18 -04:00
committed by GitHub
co-authored by Ghom
parent 8f2b69e05a
commit aa4016adfc
3 changed files with 19 additions and 14 deletions
+1 -1
View File
@@ -228,7 +228,7 @@
#define EXP_DISTRIBUTION(desired_mean) ( -(1/(1/desired_mean)) * log(rand(1, 1000) * 0.001) )
#define LORENTZ_DISTRIBUTION(x, s) ( s*tan(TODEGREES(PI*(rand()-0.5))) + x )
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*arctan((x-y)/s) + 1/2 )
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*TORADIANS(arctan((x-(y))/s)) + 1/2 )
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
+14 -9
View File
@@ -403,7 +403,7 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits)
if (SSticker.totalPlayersReady < low_pop_player_threshold)
threat_level = min(threat_level, LERP(low_pop_maximum_threat, max_threat_level, SSticker.totalPlayersReady / low_pop_player_threshold))
peaceful_percentage = clamp(round(threat_level/max_threat_level, 0.5), 0.5, 99.5)
peaceful_percentage = (threat_level/max_threat_level)*100
/// Generates the midround and roundstart budgets
/datum/game_mode/dynamic/proc/generate_budgets()
@@ -849,19 +849,24 @@ GLOBAL_LIST_EMPTY(dynamic_station_traits)
if (!isnull(threat_log))
log_threat(-cost, threat_log, reason)
#define MAXIMUM_DYN_DISTANCE 5
/**
* Returns the comulative distribution of threat centre and width, and a random location of -0.5 to 0.5
* plus or minus the otherwise unattainable lower and upper percentiles. All multiplied by the maximum
* threat and then rounded to the nearest interval.
* rand() calls without arguments returns a value between 0 and 1, allowing for smaller intervals.
*/
/datum/game_mode/dynamic/proc/lorentz_to_amount(centre, scale, max_threat = 100, interval = 1)
var/lorentz_result = LORENTZ_CUMULATIVE_DISTRIBUTION(centre, rand()-0.5, scale)
/**
* Given an x variable value of -/+5, a location of -/+ 0.5, a scale of 0.5 to 4, and a graphing calculator,
* the threat will never go beyond the upper and lower 3% of the max threat, which is why
* we're leaving the remaining 3% to the random number generator.
*/
return round(lorentz_result * max_threat + rand(-3, 3) * max_threat/100, interval)
/datum/game_mode/dynamic/proc/lorentz_to_amount(centre = 0, scale = 1.8, max_threat = 100, interval = 1)
var/location = rand(-MAXIMUM_DYN_DISTANCE, MAXIMUM_DYN_DISTANCE) * rand()
var/lorentz_result = LORENTZ_CUMULATIVE_DISTRIBUTION(centre, location, scale)
var/std_threat = lorentz_result * max_threat
///Without these, the amount won't come close to hitting 0% or 100% of the max threat.
var/lower_deviation = max(std_threat * (location-centre)/MAXIMUM_DYN_DISTANCE, 0)
var/upper_deviation = max((max_threat - std_threat) * (centre-location)/MAXIMUM_DYN_DISTANCE, 0)
return clamp(round(std_threat + upper_deviation - lower_deviation, interval), 0, 100)
#undef MAXIMUM_DYN_DISTANCE
#undef FAKE_REPORT_CHANCE
#undef FAKE_GREENSHIFT_FORM_CHANCE
@@ -1,6 +1,6 @@
// Ritual spells which affect the station at large
/// How much threat we need to let these rituals happen on dynamic
#define MINIMUM_THREAT_FOR_RITUALS 100
#define MINIMUM_THREAT_FOR_RITUALS 98
/datum/spellbook_entry/summon/ghosts
name = "Summon Ghosts"
@@ -20,7 +20,7 @@
There is a good chance that they will shoot each other first."
/datum/spellbook_entry/summon/guns/can_be_purchased()
// Summon Guns requires 100 threat.
// Summon Guns requires 98 threat.
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat_level < MINIMUM_THREAT_FOR_RITUALS)
return FALSE
@@ -38,7 +38,7 @@
why they aren't to be trusted with it at the same time."
/datum/spellbook_entry/summon/magic/can_be_purchased()
// Summon Magic requires 100 threat.
// Summon Magic requires 98 threat.
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat_level < MINIMUM_THREAT_FOR_RITUALS)
return FALSE
@@ -59,7 +59,7 @@
limit = 5 // Each purchase can intensify it.
/datum/spellbook_entry/summon/events/can_be_purchased()
// Summon Events requires 100 threat.
// Summon Events requires 98 threat.
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat_level < MINIMUM_THREAT_FOR_RITUALS)
return FALSE