diff --git a/code/datums/action.dm b/code/datums/action.dm
index f2f93ac40d..8862482dc2 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -171,7 +171,7 @@
if(!..())
return 0
var/mob/M = target
- M.ghostize(1)
+ M.ghostize(can_reenter_corpse = TRUE, voluntary = TRUE)
/datum/action/proc/OnUpdatedIcon()
UpdateButtonIcon()
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index d548f373db..32fb4498dd 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -164,7 +164,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
dat += "Current threat: [threat] \[Adjust\] \[View Log\]
"
dat += "
"
- dat += "Storyteller: [storyteller.name]
"
+ dat += "Storyteller: [storyteller.name]
"
dat += "Parameters: centre = [GLOB.dynamic_curve_centre] ; width = [GLOB.dynamic_curve_width].
"
dat += "On average, [peaceful_percentage]% of the rounds are more peaceful.
"
dat += "Forced extended: [GLOB.dynamic_forced_extended ? "On" : "Off"]
"
@@ -222,6 +222,15 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
show_threatlog(usr)
else if (href_list["stacking_limit"])
GLOB.dynamic_stacking_limit = input(usr,"Change the threat limit at which round-endings rulesets will start to stack.", "Change stacking limit", null) as num
+ else if (href_list["change_storyteller"])
+ var/list/choices = list()
+ for(var/T in config.storyteller_cache)
+ var/datum/dynamic_storyteller/S = T
+ choices[initial(S.name)] = T
+ var/selected_storyteller = choices[input("Select storyteller:", "Storyteller", storyteller.name) as null|anything in choices]
+ storyteller = new selected_storyteller
+ storyteller.on_start()
+ message_admins("[key_name(usr)] changed the storyteller to [storyteller].", 1)
admin_panel() // Refreshes the window
@@ -441,6 +450,8 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
if(!drafted_rules.len)
message_admins("Not enough threat level for roundstart antags!")
log_game("DYNAMIC: Not enough threat level for roundstart antags!")
+ midround_injection_cooldown = round((midround_injection_cooldown + world.time) / 2, 1)
+ latejoin_injection_cooldown = round((latejoin_injection_cooldown + world.time) / 2, 1)
var/indice_pop = min(10,round(roundstart_pop_ready/pop_per_requirement)+1)
extra_rulesets_amount = 0
if (GLOB.dynamic_classic_secret)
@@ -721,7 +732,8 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
if (O.started_as_observer) // Observers
current_players[CURRENT_OBSERVERS].Add(M)
continue
- current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow)
+ if(!M.voluntary_ghosted)
+ current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow)
threat = storyteller.calculate_threat() + added_threat
if(threat_average_weight)
var/cur_sample_weight = world.time - last_threat_sample_time
diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm
index 3639ada166..561b38fde1 100644
--- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm
+++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm
@@ -115,7 +115,7 @@ Property weights are:
return 100
var/threat_perc = mode.threat/mode.threat_level
- return round(max(0,100*(1-(threat_perc*threat_perc*threat_perc))))
+ return clamp(round(100*(1-(threat_perc*threat_perc))**2,1),0,100)
/datum/dynamic_storyteller/proc/roundstart_draft()
var/list/drafted_rules = list()
@@ -152,7 +152,7 @@ Property weights are:
is 2.26 times as likely to be picked, all other things considered.
Of course, we don't want it to GUARANTEE the closest, that's no fun, so it's just a weight.
*/
- threat_weight = 1-abs(1-LOGISTIC_FUNCTION(2,0.05,cost_difference,0))
+ threat_weight = abs(1-abs(1-LOGISTIC_FUNCTION(2,0.05,cost_difference,0)))
if (rule.ready())
var/property_weight = 0
for(var/property in property_weights)
@@ -209,8 +209,8 @@ Property weights are:
weight = 1
event_frequency_lower = 2 MINUTES
event_frequency_upper = 10 MINUTES
- flags = WAROPS_ALWAYS_ALLOWED
- min_players = 40
+ flags = WAROPS_ALWAYS_ALLOWED | FORCE_IF_WON
+ min_players = 30
var/refund_cooldown = 0
/datum/dynamic_storyteller/chaotic/do_process()
@@ -232,7 +232,7 @@ Property weights are:
curve_centre = 2
curve_width = 1.5
weight = 2
- min_players = 30
+ min_players = 20
flags = WAROPS_ALWAYS_ALLOWED | USE_PREV_ROUND_WEIGHTS
property_weights = list("valid" = 3, "trust" = 5)
@@ -331,7 +331,7 @@ Property weights are:
/datum/dynamic_storyteller/story/calculate_threat()
var/current_time = (world.time / SSautotransfer.targettime)*180
mode.threat_level = round(mode.initial_threat_level*(sin(current_time)+0.25),0.1)
- ..()
+ return ..()
/datum/dynamic_storyteller/classic
name = "Classic"
@@ -358,7 +358,7 @@ Property weights are:
flags = NO_ASSASSIN | FORCE_IF_WON
weight = 1
dead_player_weight = 5
- property_weights = list("extended" = 2, "chaos" = -1, "valid" = -1, "story_potential" = 1, "conversion" = -10)
+ property_weights = list("extended" = 2, "chaos" = -1, "valid" = -1, "conversion" = -10)
/datum/dynamic_storyteller/no_antag
name = "Extended"
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 118145ed88..07f95c17ff 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -405,7 +405,7 @@
// Ghost and delete the mob.
if(!mob_occupant.get_ghost(1))
- mob_occupant.ghostize(FALSE, penalize = TRUE)
+ mob_occupant.ghostize(FALSE, penalize = TRUE, voluntary = TRUE)
QDEL_NULL(occupant)
for(var/I in cryo_items) //only "CRYO_DESTROY_LATER" atoms are left)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index cbd429af5c..b040c88a49 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -364,7 +364,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
log_admin("[key_name(usr)] admin ghosted.")
message_admins("[key_name_admin(usr)] admin ghosted.")
var/mob/body = mob
- body.ghostize(1)
+ body.ghostize(1, voluntary = TRUE)
if(body && !body.key)
body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus
SSblackbox.record_feedback("tally", "admin_verb", 1, "Admin Ghost") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index 7c63266255..ff3d95598d 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -159,7 +159,7 @@
/obj/item/scrying/attack_self(mob/user)
to_chat(user, "You can see...everything!")
visible_message("[user] stares into [src], their eyes glazing over.")
- user.ghostize(1)
+ user.ghostize(1, voluntary = TRUE)
/////////////////////////////////////////Necromantic Stone///////////////////
diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm
index 2bcda1d400..f33a9a2d42 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook.dm
@@ -294,7 +294,7 @@
name = "Staff of Change"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
item_path = /obj/item/gun/magic/staff/change
- dynamic_requirement = 60
+ dynamic_requirement = 200
/datum/spellbook_entry/item/staffanimation
name = "Staff of Animation"
@@ -361,7 +361,7 @@
desc = "A collection of wands that allow for a wide variety of utility. Wands have a limited number of charges, so be conservative in use. Comes in a handy belt."
item_path = /obj/item/storage/belt/wands/full
category = "Defensive"
- dynamic_requirement = 60
+ dynamic_requirement = 200
/datum/spellbook_entry/item/armor
name = "Mastercrafted Armor Set"
diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm
index 9c89ff4a4f..ced56f0705 100644
--- a/code/modules/mob/living/simple_animal/hostile/carp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/carp.dm
@@ -7,7 +7,7 @@
icon_living = "carp"
icon_dead = "carp_dead"
icon_gib = "carp_gib"
- threat = 0.2
+ threat = 0.1
mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak_chance = 0
turns_per_move = 5
diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm
index 033187e353..87f9b55aa9 100644
--- a/code/modules/shuttle/special.dm
+++ b/code/modules/shuttle/special.dm
@@ -122,7 +122,7 @@
/obj/structure/table/abductor/wabbajack/proc/sleeper_dreams(mob/living/sleeper)
if(sleeper in sleepers)
to_chat(sleeper, "While you slumber, you have the strangest dream, like you can see yourself from the outside.")
- sleeper.ghostize(TRUE)
+ sleeper.ghostize(TRUE, voluntary = TRUE)
/obj/structure/table/abductor/wabbajack/left
desc = "You sleep so it may wake."
diff --git a/tgstation.dme b/tgstation.dme
index 29f5dbe9f7..848d149ae0 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -521,6 +521,7 @@
#include "code\datums\elements\mob_holder.dm"
#include "code\datums\elements\polychromic.dm"
#include "code\datums\elements\spellcasting.dm"
+#include "code\datums\elements\squish.dm"
#include "code\datums\elements\swimming.dm"
#include "code\datums\elements\sword_point.dm"
#include "code\datums\elements\update_icon_blocker.dm"