diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm
index 9a78ba24b233..c45ff7b5e744 100644
--- a/code/datums/mind/_mind.dm
+++ b/code/datums/mind/_mind.dm
@@ -105,6 +105,8 @@
var/list/failed_special_equipment
/// A list to keep track of which books a person has read (to prevent people from reading the same book again and again for positive mood events)
var/list/book_titles_read
+ /// Variable that lets the event picker see if someones getting chosen or not
+ var/picking = FALSE
/datum/mind/New(_key)
key = _key
diff --git a/code/datums/mind/antag.dm b/code/datums/mind/antag.dm
index b864bde8bd5d..c252f275836d 100644
--- a/code/datums/mind/antag.dm
+++ b/code/datums/mind/antag.dm
@@ -25,6 +25,8 @@
antag_team.add_member(src)
INVOKE_ASYNC(A, TYPE_PROC_REF(/datum/antagonist, on_gain))
log_game("[key_name(src)] has gained antag datum [A.name]([A.type]).")
+ var/client/picked_client = get_player_client(src)
+ picked_client?.mob?.mind.picking = FALSE
return A
/datum/mind/proc/remove_antag_datum(datum_type)
diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_authentication_disk.dm b/code/modules/antagonists/nukeop/equipment/nuclear_authentication_disk.dm
index 965eda0784f4..960ab849041f 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclear_authentication_disk.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclear_authentication_disk.dm
@@ -40,6 +40,7 @@
var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control
if(istype(loneop) && loneop.occurrences < loneop.max_occurrences && prob(loneop.weight))
loneop.weight = max(loneop.weight - 1, 0)
+ loneop.checks_antag_cap = (loneop.weight < 3)
if(loneop.weight % 5 == 0 && SSticker.totalPlayers > 1)
message_admins("[src] is secured (currently in [ADMIN_VERBOSEJMP(new_turf)]). The weight of Lone Operative is now [loneop.weight].")
log_game("[src] being secured has reduced the weight of the Lone Operative event to [loneop.weight].")
@@ -57,6 +58,7 @@
if(last_move < world.time - 500 SECONDS && prob((world.time - 500 SECONDS - last_move)*0.0001))
var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control
if(istype(loneop) && loneop.occurrences < loneop.max_occurrences)
+ loneop.checks_antag_cap = (loneop.weight < 3)
loneop.weight += 1
if(loneop.weight % 5 == 0 && SSticker.totalPlayers > 1)
if(disk_comfort_level >= 2)
@@ -64,6 +66,7 @@
message_admins("[src] is unsecured in [ADMIN_VERBOSEJMP(new_turf)]. The weight of Lone Operative is now [loneop.weight].")
log_game("[src] was left unsecured in [loc_name(new_turf)]. Weight of the Lone Operative event increased to [loneop.weight].")
+
/obj/item/disk/nuclear/examine(mob/user)
. = ..()
if(!fake)
diff --git a/code/modules/mob/living/basic/drone/_drone.dm b/code/modules/mob/living/basic/drone/_drone.dm
index 061ca478bc42..f42a439f1e15 100644
--- a/code/modules/mob/living/basic/drone/_drone.dm
+++ b/code/modules/mob/living/basic/drone/_drone.dm
@@ -100,7 +100,8 @@
" - Interacting with non-living beings (dragging bodies, looting bodies, etc.)\n"+\
"These rules are at admin discretion and will be heavily enforced.\n"+\
"If you do not have the regular drone laws, follow your laws to the best of your ability.\n"+\
- "Prefix your message with :b to speak in Drone Chat.\n"
+ "Prefix your message with :b to speak in Drone Chat.\n"+\
+ "Drone Rules and info can be found at our wiki HERE\n"
/// blacklisted drone areas, direct
var/list/drone_area_blacklist_flat = list(/area/station/engineering/atmos, /area/station/engineering/atmospherics_engine)
/// blacklisted drone areas, recursive/includes descendants
diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm
index ae4dd19fc820..1d10a32f9959 100644
--- a/code/modules/shuttle/special.dm
+++ b/code/modules/shuttle/special.dm
@@ -150,18 +150,47 @@
// Bar staff, GODMODE mobs(as long as they stay in the shuttle) that just want to make sure people have drinks
// and a good time.
+/obj/item/storage/backpack/duffelbag/bardrone
+ name = "Bardrones Duffelbag"
+ desc = "A funny little bag for funny little drones"
+ icon_state = "duffel"
+ inhand_icon_state = "duffel"
+
+/obj/item/storage/backpack/duffelbag/bardrone/PopulateContents()
+ new /obj/item/reagent_containers/cup/glass/shaker(src)
+ new /obj/item/storage/box/drinkingglasses(src)
+ new /obj/item/reagent_containers/cup/rag(src)
+ new /obj/item/storage/fancy/cigarettes/cigars/havana(src)
+
/mob/living/basic/drone/snowflake/bardrone
name = "Bardrone"
- desc = "A barkeeping drone, a robot built to tend bars."
+ desc = "A barkeeping drone, a robot built to tend and maintain bars."
+ default_storage = /obj/item/storage/backpack/duffelbag/bardrone
hacked = TRUE
shy = FALSE
laws = "1. Serve drinks.\n\
2. Talk to patrons.\n\
- 3. Don't get messed up in their affairs."
+ 3. Maintain the integrity of the bar.\n\
+ 4. Do NOT involve yourself in the affairs of others outside of the above laws\n\
+ 5. If given permission by relevant owners, you may improve the bar you have chosen to operate at."
+
unique_name = FALSE // disables the (123) number suffix
initial_language_holder = /datum/language_holder/universal
default_storage = null
+ flavortext = \
+ "\nLAW EXPLANATION FOR BAR DRONES\n"+\
+ "As a bar drone your goal is to provide a fun interactive experience for other players visiting the bar*. \n"+\
+ "BARDRONE GUIDELINES\n"+\
+ " -Do not harm sapient creatures \n"+\
+ " -Do not interact with non-concious people, including dead, passed out, or SSD. Call medical instead.\n"+\
+ " -Do not get into altercations with other players, remove yourself from the situation. \n"+\
+ " -Do not protect the bar from agressors. \n"+\
+ " -You may decide what bar you wish to operate at as long as the users/owners of that bar also agree.\n"+\
+ " -You may create your own bar with permission from a relevant head of staff. Do not monopolize station resources. \n"+\
+ "These rules are at admin discretion and will be heavily enforced. If you have questions about these rules AHELP it.\n"+\
+ "\n"+\
+ "Prefix your message with :b to speak in Drone Chat.\n"
/mob/living/basic/drone/snowflake/bardrone/Initialize(mapload)
. = ..()
diff --git a/monkestation/code/modules/blueshift/items/ammo.dm b/monkestation/code/modules/blueshift/items/ammo.dm
index d06142daabe2..5d36f0595140 100644
--- a/monkestation/code/modules/blueshift/items/ammo.dm
+++ b/monkestation/code/modules/blueshift/items/ammo.dm
@@ -1301,7 +1301,7 @@
icon_state = "lasershell"
projectile_type = /obj/projectile/bullet/pellet/shotgun_buckshot/antitide
pellets = 8 // 8 * 7 for 56 stamina damage, plus whatever the embedded shells do
- variance = 30
+ variance = 50
harmful = FALSE
fire_sound = 'sound/weapons/taser.ogg'
custom_materials = AMMO_MATS_SHOTGUN_TIDE
@@ -1312,14 +1312,14 @@
icon = 'monkestation/code/modules/blueshift/icons/projectiles.dmi'
icon_state = "stardust"
damage = 2
- stamina = 16
+ stamina = 10
wound_bonus = 0
bare_wound_bonus = 0
stutter = 3 SECONDS
jitter = 5 SECONDS
eyeblur = 1 SECONDS
sharpness = NONE
- range = 8
+ range = 7
embedding = list(embed_chance=70, pain_chance=25, fall_chance=15, jostle_chance=80, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.9, pain_mult=2, rip_time=10)
/obj/projectile/bullet/pellet/shotgun_buckshot/antitide/on_range()
diff --git a/monkestation/code/modules/slimecore/crossbreeding/regenerative/colors.dm b/monkestation/code/modules/slimecore/crossbreeding/regenerative/colors.dm
index 7c279e461d55..67a0fcbb9773 100644
--- a/monkestation/code/modules/slimecore/crossbreeding/regenerative/colors.dm
+++ b/monkestation/code/modules/slimecore/crossbreeding/regenerative/colors.dm
@@ -25,20 +25,12 @@
/datum/status_effect/regenerative_extract/adamantine
extra_traits = list(TRAIT_FEARLESS, TRAIT_HARDLY_WOUNDED)
-// rainbow extracts are similar to old regen extract effects, albeit it won't replace your organs, and won't heal limbs (unless you're an oozeling)
-#define RAINBOW_HEAL_FLAGS ~(HEAL_ADMIN | HEAL_RESTRAINTS | HEAL_LIMBS | HEAL_REFRESH_ORGANS)
-
+// rainbow extracts are similar to old regen extract effects, albeit it won't replace your organs, and won't heal limbs
/datum/status_effect/regenerative_extract/rainbow
- alert_type = null
- diminishing_multiplier = 0 // you can't use other extracts at all during this time
- tick_interval = -1
-
-/datum/status_effect/regenerative_extract/rainbow/on_apply()
- var/heal_flags = RAINBOW_HEAL_FLAGS
- if(isoozeling(owner)) // have some mercy on oozelings
- heal_flags |= HEAL_LIMBS
- owner.revive(heal_flags)
- return FALSE // return false so we immediately clear the effect and start the cooldown
-
+ duration = 30 SECONDS
+ base_healing_amt = 15
+ diminishing_multiplier = 1
+ diminish_time = 1.5 MINUTES
+ extra_traits = list(TRAIT_NOCRITOVERLAY, TRAIT_NOSOFTCRIT, TRAIT_NOHARDCRIT)
+ pain_amount = 80 //wow having my wounds closed up in seconds really fucking HURTS
-#undef RAINBOW_HEAL_FLAGS
diff --git a/monkestation/code/modules/slimecore/crossbreeding/regenerative/effect.dm b/monkestation/code/modules/slimecore/crossbreeding/regenerative/effect.dm
index 763b98a02068..f1f4878fd76b 100644
--- a/monkestation/code/modules/slimecore/crossbreeding/regenerative/effect.dm
+++ b/monkestation/code/modules/slimecore/crossbreeding/regenerative/effect.dm
@@ -14,13 +14,15 @@
/// The multiplier that the cooldown applied after the effect ends will use.
var/diminishing_multiplier = 0.75
/// How long the subsequent cooldown effect will last.
- var/diminish_time = 45 SECONDS
+ var/diminish_time = 90 SECONDS
/// The maximum nutrition level this regenerative extract can heal up to.
var/nutrition_heal_cap = NUTRITION_LEVEL_FED - 50
/// Base traits given to the owner.
var/static/list/given_traits = list(TRAIT_ANALGESIA, TRAIT_NOCRITDAMAGE)
/// Extra traits given to the owner, added to the base traits.
var/list/extra_traits
+ //Slime healing cause pain, oof ouch
+ var/pain_amount = 20
/datum/status_effect/regenerative_extract/on_apply()
// So this seems weird, but this allows us to have multiple things affect the regen multiplier,
@@ -35,6 +37,7 @@
/datum/status_effect/regenerative_extract/on_remove()
owner.remove_traits(islist(extra_traits) ? (given_traits + extra_traits) : given_traits, id)
owner.apply_status_effect(/datum/status_effect/slime_regen_cooldown, diminishing_multiplier, diminish_time)
+ owner.cause_pain(BODY_ZONE_CHEST, pain_amount, BRUTE)
/datum/status_effect/regenerative_extract/tick(seconds_per_tick, times_fired)
var/heal_amt = base_healing_amt * seconds_per_tick * multiplier
@@ -58,11 +61,12 @@
owner.adjustCloneLoss(-heal_amt, updating_health = FALSE)
/datum/status_effect/regenerative_extract/proc/heal_misc(heal_amt)
- owner.adjust_disgust(-heal_amt)
+ var/blood_restore = (heal_amt * 0.25)
+ owner.adjust_disgust(-blood_restore)
if(owner.blood_volume < BLOOD_VOLUME_NORMAL)
- owner.blood_volume = min(owner.blood_volume + heal_amt, BLOOD_VOLUME_NORMAL)
+ owner.blood_volume = min(owner.blood_volume + blood_restore, BLOOD_VOLUME_NORMAL)
if((owner.nutrition < nutrition_heal_cap) && !HAS_TRAIT(owner, TRAIT_NOHUNGER))
- owner.nutrition = min(owner.nutrition + heal_amt, nutrition_heal_cap)
+ owner.nutrition = min(owner.nutrition + blood_restore, nutrition_heal_cap)
/datum/status_effect/regenerative_extract/proc/heal_organs(heal_amt)
var/static/list/ignored_traumas
@@ -93,5 +97,5 @@
/atom/movable/screen/alert/status_effect/regen_extract
name = "Slime Regeneration"
- desc = "A milky slime covers your skin, soothing and regenerating your injuries!"
+ desc = "A milky slime covers your skin, regenerating your injuries!"
icon_state = "regenerative_core"
diff --git a/monkestation/code/modules/storytellers/converted_events/_base_event.dm b/monkestation/code/modules/storytellers/converted_events/_base_event.dm
index 4335c4386191..d003254aaa8d 100644
--- a/monkestation/code/modules/storytellers/converted_events/_base_event.dm
+++ b/monkestation/code/modules/storytellers/converted_events/_base_event.dm
@@ -241,6 +241,7 @@
var/list/cliented_list = list()
for(var/mob/living/mob as anything in possible_candidates)
cliented_list += mob.client
+
if(length(cliented_list))
mass_adjust_antag_rep(cliented_list, 1)
@@ -272,6 +273,7 @@
if(QDELETED(picked_client))
continue
var/mob/picked_mob = picked_client.mob
+ picked_mob?.mind?.picking = TRUE
log_storyteller("Picked antag event mob: [picked_mob], special role: [picked_mob.mind?.special_role ? picked_mob.mind.special_role : "none"]")
candidates |= picked_mob
diff --git a/monkestation/code/modules/storytellers/gamemode_subsystem.dm b/monkestation/code/modules/storytellers/gamemode_subsystem.dm
index b8a1179eb9b7..0c3a23f31d66 100644
--- a/monkestation/code/modules/storytellers/gamemode_subsystem.dm
+++ b/monkestation/code/modules/storytellers/gamemode_subsystem.dm
@@ -262,6 +262,8 @@ SUBSYSTEM_DEF(gamemode)
var/list/candidate_candidates = list() //lol
for(var/mob/player as anything in GLOB.player_list)
+ if(QDELETED(player) || player.mind?.picking)
+ continue
if(ready_newplayers && isnewplayer(player))
var/mob/dead/new_player/new_player = player
if(new_player.ready == PLAYER_READY_TO_PLAY && new_player.mind && new_player.check_preferences())
diff --git a/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx b/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx
index 1b4d2d6f8bbc..f4855f47cfc6 100644
--- a/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx
+++ b/tgui/packages/tgui/interfaces/AntagInfoChangeling.tsx
@@ -119,8 +119,12 @@ const HivemindSection = (props) => {
you. Changelings grow in power greatly by absorbing their kind, and
getting absorbed by another Changeling will leave you as a{' '}
Fallen Changeling. There is no
- greater humiliation.
+ greater humiliation.{'\n'}
+ Additionally changeling rules can be found under{' '}
+
+ Antagonist Guidance.
+