New equation for threat

This commit is contained in:
Shifty/Anthomansland
2019-04-11 23:13:58 +02:00
parent f666d03b45
commit 48070d2ec4
4 changed files with 125 additions and 2 deletions

View File

@@ -13,6 +13,11 @@ var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10)
*/
// Returns y so that y/x = a/b.
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
#define tan(x) (sin(x)/cos(x))
/proc/Atan2(x, y)
if (!x && !y)
return 0
@@ -35,6 +40,20 @@ proc/arctan(x)
else
return 0
// -- Returns a Lorentz-distributed number.
// -- The probability density function has centre x0 and width s.
/proc/lorentz_distribution(var/x0, var/s)
var/x = rand()
var/y = s*tan_rad(PI*(x-0.5)) + x0
return y
// -- Returns the Lorentz cummulative distribution of the real x.
/proc/lorentz_cummulative_distribution(var/x, var/x0, var/s)
var/y = (1/PI)*ToRadians(arctan((x-x0)/s)) + 1/2
return y
//Moved to macros.dm to reduce pure calling overhead, this was being called shitloads, like, most calls of all procs.
/*
/proc/Clamp(const/val, const/min, const/max)
@@ -188,9 +207,13 @@ proc/arctan(x)
/*
* Tangent.
*/
/proc/Tan(const/x)
/proc/Tan(const/x)
return sin(x) / cos(x)
/proc/tan_rad(const/x) // This one assumes that x is in radians.
return Tan(ToDegrees(x))
/proc/ToDegrees(const/radians)
// 180 / Pi
return radians * 57.2957795

View File

@@ -9,8 +9,47 @@ var/list/threat_by_job = list(
"Detective" = 3,
)
var/dynamic_curve_centre = 0
var/dynamic_curve_width = 1.8
#define BASE_SOLO_REFUND 10
/proc/lorentz2threat(var/x)
var/y
switch (x)
// Left end of the tail, the lowest bound is -inf.
// 0 to 10.
if (-INFINITY to -20)
y = rand(0, 10)
// Porportional conversion from the lorentz variable to the threa.
// First, we use a rule of three to get a number from -40 to -30.
// Then we shift it by 50 to get a number from 10 to 20.
// The same process is done for other intervalls.
if (-20 to -10)
y = RULE_OF_THREE(-40, -20, x) + 50
if (-10 to -5)
y = RULE_OF_THREE(-30, -10, x) + 50
if (-5 to -2.5)
y = RULE_OF_THREE(-20, -5, x) + 50
if (-2.5 to -0)
y = RULE_OF_THREE(-10, -2.5, x) + 50
if (0 to 2.5)
y = RULE_OF_THREE(10, 2.5, x) + 50
if (2.5 to 5)
y = RULE_OF_THREE(20, 5, x) + 50
if (5 to 10)
y = RULE_OF_THREE(30, 10, x) + 50
if (10 to 20)
y = RULE_OF_THREE(40, 20, x) + 50
// Right end of the tail, higher bound is +inf.
if (20 to INFINITY)
y = rand(90, 100)
return y
/datum/gamemode/dynamic
name = "Dynamic Mode"
@@ -43,11 +82,19 @@ var/list/threat_by_job = list(
var/datum/stat/dynamic_mode/dynamic_stats = null
var/pop_last_updated = 0
var/relative_threat = 0 // Relative threat, Lorentz-distributed.
var/curve_centre_of_round = 0
var/curve_width_of_round = 1.8
var/peaceful_percentage = 50
/datum/gamemode/dynamic/AdminPanelEntry()
var/dat = list()
dat += "Dynamic Mode <a href='?_src_=vars;Vars=\ref[src]'>\[VV\]</A><BR>"
dat += "Threat Level: <b>[threat_level]</b><br/>"
dat += "Threat to Spend: <b>[threat]</b> <a href='?_src_=holder;adjustthreat=1'>\[Adjust\]</A> <a href='?_src_=holder;threatlog=1'>\[View Log\]</a><br/>"
dat += "Parameters: centre = [curve_centre_of_round] ; width = [curve_width_of_round].<br/>"
dat += "<i>On average, <b>[peaceful_percentage]</b>% of the rounds are more peaceful.</i><br/>"
dat += "Executed rulesets: "
if (executed_rules.len > 0)
dat += "<br/>"
@@ -112,13 +159,30 @@ var/list/threat_by_job = list(
send2maindiscord("Dynamic mode threat: **[threat_level]**, rulesets: [jointext(rules, ", ")]")
/datum/gamemode/dynamic/can_start()
threat_level = rand(1,100)*0.6 + rand(1,100)*0.4//https://docs.google.com/spreadsheets/d/1QLN_OBHqeL4cm9zTLEtxlnaJHHUu0IUPzPbsI-DFFmc/edit#gid=499381388
// Old equation.
//threat_level = rand(1,100)*0.6 + rand(1,100)*0.4//https://docs.google.com/spreadsheets/d/1QLN_OBHqeL4cm9zTLEtxlnaJHHUu0IUPzPbsI-DFFmc/edit#gid=499381388
// New equation : https://docs.google.com/spreadsheets/d/1qnQm5hDdwZoyVmBCtf6-jwwHKEaCnYa3ljmYPs7gkSE/edit#gid=0
relative_threat = lorentz_distribution(dynamic_curve_centre, dynamic_curve_width)
threat_level = lorentz2threat(relative_threat)
threat = round(threat, 0.1)
peaceful_percentage = round(lorentz_cummulative_distribution(relative_threat, curve_centre_of_round, curve_width_of_round), 0.01)*100
curve_centre_of_round = dynamic_curve_centre
curve_width_of_round = dynamic_curve_width
threat = threat_level
starting_threat = threat_level
latejoin_injection_cooldown = rand(330,510)
midround_injection_cooldown = rand(600,1050)
message_admins("Dynamic Mode initialized with a Threat Level of... <font size='8'>[threat_level]</font>!")
log_admin("Dynamic Mode initialized with a Threat Level of... [threat_level]!")
message_admins("Parameters were: centre = [curve_centre_of_round], width = [curve_width_of_round].")
log_admin("Parameters were: centre = [curve_centre_of_round], width = [curve_width_of_round].")
if (config.high_population_override)
message_admins("High Population Override is in effect! Threat Level will have more impact on which roles will appear, and player population less.")
log_admin("High Population Override is in effect! Threat Level will have more impact on which roles will appear, and player population less.")

View File

@@ -687,6 +687,9 @@ var/global/floorIsLava = 0
for(var/datum/dynamic_ruleset/roundstart/rule in forced_roundstart_ruleset)
dat += {"<A href='?src=\ref[src];f_dynamic_roundstart_remove=\ref[rule]'>-> [rule.name] <-</A><br>"}
dat += "<A href='?src=\ref[src];f_dynamic_roundstart_clear=1'>(Clear Rulesets)</A><br>"
dat += "Parameters: <br/>"
dat += {"Curve centre: <A href='?src=\ref[src];f_dynamic_roundstart_centre=1'>-> [dynamic_curve_centre] <-</A><br>"}
dat += {"Curve width: <A href='?src=\ref[src];f_dynamic_roundstart_width=1'>-> [dynamic_curve_width] <-</A><br>"}
else
dat += "<A href='?src=\ref[src];f_dynamic_latejoin=1'>(Force Next Latejoin Ruleset)</A><br>"
if (ticker && ticker.mode && istype(ticker.mode,/datum/gamemode/dynamic))

View File

@@ -1557,6 +1557,39 @@
mode.picking_specific_rule(midround_rules[added_rule],1)
else if(href_list["f_dynamic_roundstart_centre"])
if(!check_rights(R_ADMIN))
return
if(ticker && ticker.mode)
return alert(usr, "The game has already started.", null, null, null, null)
if(master_mode != "Dynamic Mode")
return alert(usr, "The game mode has to be Dynamic Mode!", null, null, null, null)
var/new_centre = input(usr,"Change the centre of the dynamic mode threat curve. A negative value will give a more peaceful round ; a positive value, a round with higher threat. Any number between -5 and +5 is allowed.", "Change curve centre", null) as num
if (new_centre < -5 || new_centre > 5)
return alert(usr, "Only values between -5 and +5 are allowed.", null, null, null, null)
log_admin("[key_name(usr)] changed the distribution curve center to [new_centre].")
message_admins("[key_name(usr)] changed the distribution curve center to [new_centre]", 1)
dynamic_curve_centre = new_centre
else if(href_list["f_dynamic_roundstart_width"])
if(!check_rights(R_ADMIN))
return
if(ticker && ticker.mode)
return alert(usr, "The game has already started.", null, null, null, null)
if(master_mode != "Dynamic Mode")
return alert(usr, "The game mode has to be Dynamic Mode!", null, null, null, null)
var/new_width = input(usr,"Change the width of the dynamic mode threat curve. A higher value will favour extreme rounds ; a lower value, a round closer to the average. Any Number between 0.5 and 4 are allowed.", "Change curve width", null) as num
if (new_width < 0.5 || new_width > 4)
return alert(usr, "Only values between 0.5 and +2.5 are allowed.", null, null, null, null)
log_admin("[key_name(usr)] changed the distribution curve width to [new_width].")
message_admins("[key_name(usr)] changed the distribution curve width to [new_width]", 1)
dynamic_curve_width = new_width
else if(href_list["c_mode2"])
if(!check_rights(R_ADMIN|R_SERVER))