diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/Delta/delta.dmm
index 3e6c7e5c478..a89ac854596 100644
--- a/_maps/map_files/Delta/delta.dmm
+++ b/_maps/map_files/Delta/delta.dmm
@@ -78837,7 +78837,7 @@
/turf/simulated/floor/plasteel,
/area/toxins/xenobiology)
"cKn" = (
-/mob/living/carbon/slime,
+/mob/living/simple_animal/slime,
/turf/simulated/floor/greengrid,
/area/toxins/xenobiology)
"cKo" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
index 41beb0d3a35..4396c52587d 100644
--- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
@@ -23103,7 +23103,7 @@
/turf/simulated/floor/plasteel,
/area/storage/tools)
"aOE" = (
-/mob/living/carbon/slime,
+/mob/living/simple_animal/slime,
/turf/simulated/floor/plasteel,
/area/toxins/xenobiology{
name = "\improper Secure Lab"
diff --git a/_maps/map_files/MetaStation/z2.dmm b/_maps/map_files/MetaStation/z2.dmm
index 4dcf9a2797b..446079ebd0c 100644
--- a/_maps/map_files/MetaStation/z2.dmm
+++ b/_maps/map_files/MetaStation/z2.dmm
@@ -4443,7 +4443,7 @@
"mp" = (
/obj/effect/decal/cleanable/blood/splatter,
/obj/structure/rack,
-/obj/item/clothing/suit/space/hardsuit/wizard,
+/obj/item/clothing/suit/space/hardsuit/shielded/wizard,
/turf/unsimulated/floor{
tag = "icon-cultdamage";
icon_state = "cultdamage"
diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm
index b097156d39a..1bba42283c2 100644
--- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm
+++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm
@@ -30,7 +30,7 @@
/turf/simulated/floor/plasteel/freezer,
/area/ruin/powered/seedvault)
"f" = (
-/obj/machinery/plantgenes/upgraded{
+/obj/machinery/plantgenes/seedvault{
pixel_y = 6
},
/obj/structure/table/wood,
diff --git a/_maps/map_files/RandomZLevels/academy.dmm b/_maps/map_files/RandomZLevels/academy.dmm
index 87f3573eb00..03c8b8919e4 100644
--- a/_maps/map_files/RandomZLevels/academy.dmm
+++ b/_maps/map_files/RandomZLevels/academy.dmm
@@ -238,7 +238,7 @@
/turf/simulated/floor/wood,
/area/awaymission/academy/headmaster)
"aL" = (
-/obj/item/clothing/suit/space/hardsuit/wizard,
+/obj/item/clothing/suit/space/hardsuit/shielded/wizard,
/obj/structure/table/wood,
/obj/item/stack/sheet/mineral/silver{
amount = 20
diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index 2162c77926e..02bd3ad1e7c 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -79739,7 +79739,7 @@
/obj/effect/landmark{
name = "revenantspawn"
},
-/mob/living/carbon/slime,
+/mob/living/simple_animal/slime,
/turf/simulated/floor/engine,
/area/toxins/xenobiology)
"cMh" = (
@@ -81166,7 +81166,7 @@
},
/area/toxins/xenobiology)
"cOS" = (
-/obj/machinery/optable,
+/obj/structure/table,
/turf/simulated/floor/plasteel{
icon_state = "white"
},
@@ -81933,10 +81933,8 @@
/area/toxins/xenobiology)
"cQt" = (
/obj/structure/table/reinforced,
-/obj/item/circular_saw{
- pixel_y = 0
- },
/obj/item/scalpel,
+/obj/item/hemostat,
/turf/simulated/floor/plasteel{
icon_state = "white"
},
diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm
index c7620721a8c..ffb4f0fbc7f 100644
--- a/_maps/map_files/cyberiad/z2.dmm
+++ b/_maps/map_files/cyberiad/z2.dmm
@@ -4300,6 +4300,9 @@
/obj/structure/table/abductor,
/obj/item/surgicaldrill/alien,
/obj/item/circular_saw/alien,
+/obj/item/FixOVein/alien,
+/obj/item/bonesetter/alien,
+/obj/item/bonegel/alien,
/turf/unsimulated/floor/abductor,
/area/abductor_ship)
"ll" = (
@@ -9053,7 +9056,7 @@
pixel_x = -3;
pixel_y = 3
},
-/obj/item/clothing/suit/space/hardsuit/wizard,
+/obj/item/clothing/suit/space/hardsuit/shielded/wizard,
/obj/item/clothing/suit/space/santa{
pixel_x = 3;
pixel_y = -3
diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
index bec3a6075dc..8c63ed7dad6 100644
--- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
@@ -403,9 +403,9 @@
/obj/machinery/atmospherics/unary/vent_pump/examine(mob/user)
- ..(user)
+ . = ..()
if(welded)
- to_chat(user, "It seems welded shut.")
+ . += "It seems welded shut."
/obj/machinery/atmospherics/unary/vent_pump/power_change()
var/old_stat = stat
diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
index 99ee514a1cc..5fcf7817a30 100644
--- a/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/vent_scrubber.dm
@@ -65,9 +65,9 @@
return ..()
/obj/machinery/atmospherics/unary/vent_pump/examine(mob/user)
- ..(user)
+ . = ..()
if(welded)
- to_chat(user, "It seems welded shut.")
+ . += "It seems welded shut."
/obj/machinery/atmospherics/unary/vent_scrubber/auto_use_power()
if(!powered(power_channel))
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index b3b86ac13e1..df957eaa11e 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -40,7 +40,7 @@
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
#define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
-#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob)
+#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob, result)
#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides)
//Positions for overrides list
#define EXAMINE_POSITION_ARTICLE 1
diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm
index 6afa76a02b0..c8916e31f40 100644
--- a/code/__DEFINES/genetics.dm
+++ b/code/__DEFINES/genetics.dm
@@ -165,4 +165,5 @@
#define NOZOMBIE 20
#define NO_GERMS 21
#define NO_DECAY 22
-#define PIERCEIMMUNE 23
\ No newline at end of file
+#define PIERCEIMMUNE 23
+#define NO_HUNGER 24
\ No newline at end of file
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index d0ba27fb3d8..33ce299c540 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -86,7 +86,7 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
#define isaliensentinel(A) (istype(A, /mob/living/carbon/alien/humanoid/sentinel))
-#define isslime(A) (istype((A), /mob/living/carbon/slime))
+#define isslime(A) (istype((A), /mob/living/simple_animal/slime))
//Structures
#define isstructure(A) (istype((A), /obj/structure))
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index a9e43b7c3a0..7dd5fc5a609 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -417,3 +417,6 @@
#define ENGTYPE_SING "Singularity"
#define ENGTYPE_SM "Supermatter"
#define ENGTYPE_TESLA "Tesla"
+
+#define SUMMON_GUNS "guns"
+#define SUMMON_MAGIC "magic"
\ No newline at end of file
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 25540dd4965..1db82f879fe 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -67,8 +67,8 @@
// Taste sensitivity - lower is more sensitive
// Represents the minimum portion of total taste the mob can sense
#define TASTE_SENSITIVITY_NORMAL 15
-#define TASTE_SENSITIVITY_SHARP 7.5
-#define TASTE_SENSITIVITY_DULL 20
+#define TASTE_SENSITIVITY_SHARP 10
+#define TASTE_SENSITIVITY_DULL 25
#define TASTE_SENSITIVITY_NO_TASTE 101
// Reagent type flags, defines the types of mobs this reagent will affect
@@ -95,6 +95,21 @@
#define APPEARANCE_ALL_BODY APPEARANCE_ALL_HAIR|APPEARANCE_HEAD_ACCESSORY|APPEARANCE_MARKINGS|APPEARANCE_BODY_ACCESSORY|APPEARANCE_ALT_HEAD
#define APPEARANCE_ALL 32767
+//Slime evolution threshold. Controls how fast slimes can split/grow
+#define SLIME_EVOLUTION_THRESHOLD 10
+
+//Slime extract crossing. Controls how many extracts is required to feed to a slime to core-cross.
+#define SLIME_EXTRACT_CROSSING_REQUIRED 10
+
+//Slime commands defines
+#define SLIME_FRIENDSHIP_FOLLOW 3 //Min friendship to order it to follow
+#define SLIME_FRIENDSHIP_STOPEAT 5 //Min friendship to order it to stop eating someone
+#define SLIME_FRIENDSHIP_STOPEAT_NOANGRY 7 //Min friendship to order it to stop eating someone without it losing friendship
+#define SLIME_FRIENDSHIP_STOPCHASE 4 //Min friendship to order it to stop chasing someone (their target)
+#define SLIME_FRIENDSHIP_STOPCHASE_NOANGRY 6 //Min friendship to order it to stop chasing someone (their target) without it losing friendship
+#define SLIME_FRIENDSHIP_STAY 3 //Min friendship to order it to stay
+#define SLIME_FRIENDSHIP_ATTACK 8 //Min friendship to order it to attack
+
//If you add a new status, be sure to add a list for it to the simple_animals global in _globalvars/lists/mobs.dm
//Hostile Mob AI Status
#define AI_ON 1
@@ -200,7 +215,7 @@
// For the tcomms monitor
#define ispathhuman(A) (ispath(A, /mob/living/carbon/human))
#define ispathbrain(A) (ispath(A, /mob/living/carbon/brain))
-#define ispathslime(A) (ispath(A, /mob/living/carbon/slime))
+#define ispathslime(A) (ispath(A, /mob/living/simple_animal/slime))
#define ispathbot(A) (ispath(A, /mob/living/simple_animal/bot))
#define ispathsilicon(A) (ispath(A, /mob/living/silicon))
#define ispathanimal(A) (ispath(A, /mob/living/simple_animal))
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 34ad4d69e54..5b93e570222 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -10,6 +10,7 @@
// justice if someone's abusing your role
#define ROLE_SYNDICATE "Syndicate"
#define ROLE_TRAITOR "traitor"
+#define ROLE_MINDSLAVE "mindslave"
#define ROLE_OPERATIVE "operative"
#define ROLE_CHANGELING "changeling"
#define ROLE_WIZARD "wizard"
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 10759fe336a..82295bc9d80 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -166,6 +166,18 @@ Turf and target are seperate in case you want to teleport some distance from a t
return destination
+
+/proc/is_in_teleport_proof_area(atom/O)
+ if(!O)
+ return FALSE
+ var/area/A = get_area(O)
+ if(!A)
+ return FALSE
+ if(A.tele_proof)
+ return TRUE
+ else
+ return FALSE
+
// Returns true if direction is blocked from loc
// Checks if doors are open
/proc/DirBlocked(turf/loc,var/dir)
@@ -409,7 +421,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
moblist.Add(M)
for(var/mob/new_player/M in sortmob)
moblist.Add(M)
- for(var/mob/living/carbon/slime/M in sortmob)
+ for(var/mob/living/simple_animal/slime/M in sortmob)
moblist.Add(M)
for(var/mob/living/simple_animal/M in sortmob)
moblist.Add(M)
@@ -1518,6 +1530,23 @@ var/mob/dview/dview_mob = new
return FALSE
return TRUE
+//datum may be null, but it does need to be a typed var
+#define NAMEOF(datum, X) (#X || ##datum.##X)
+
+#define VARSET_LIST_CALLBACK(target, var_name, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##target, ##var_name, ##var_value)
+//dupe code because dm can't handle 3 level deep macros
+#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##datum, NAMEOF(##datum, ##var), ##var_value)
+
+/proc/___callbackvarset(list_or_datum, var_name, var_value)
+ if(length(list_or_datum))
+ list_or_datum[var_name] = var_value
+ return
+ var/datum/D = list_or_datum
+ if(IsAdminAdvancedProcCall())
+ D.vv_edit_var(var_name, var_value) //same result generally, unless badmemes
+ else
+ D.vars[var_name] = var_value
+
//Get the dir to the RIGHT of dir if they were on a clock
//NORTH --> NORTHEAST
/proc/get_clockwise_dir(dir)
diff --git a/code/_onclick/hud/slime.dm b/code/_onclick/hud/slime.dm
index 9f5621b75ee..f49228ddf66 100644
--- a/code/_onclick/hud/slime.dm
+++ b/code/_onclick/hud/slime.dm
@@ -1,18 +1,8 @@
-/mob/living/carbon/slime/create_mob_hud()
- if(client && !hud_used)
- hud_used = new /datum/hud/slime(src)
-
-/mob/living/simple_animal/slime/create_mob_hud()
- if(client && !hud_used)
- hud_used = new /datum/hud/slime(src)
-
-/datum/hud/slime/New(mob/owner)
+/datum/hud/slime/New(mob/living/simple_animal/slime/owner, ui_style = 'icons/mob/screen_slime.dmi')
..()
mymob.healths = new /obj/screen/healths/slime()
infodisplay += mymob.healths
- mymob.pullin = new /obj/screen/pull()
- mymob.pullin.icon = 'icons/mob/screen_slime.dmi'
- mymob.pullin.update_icon(mymob)
- mymob.pullin.screen_loc = ui_construct_pull
- hotkeybuttons += mymob.pullin
+/mob/living/simple_animal/slime/create_mob_hud()
+ if(client && !hud_used)
+ hud_used = new /datum/hud/slime(src)
\ No newline at end of file
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index c9c304729d8..47857ee4fa1 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -87,11 +87,13 @@
Slimes
Nothing happening here
*/
-/mob/living/carbon/slime/UnarmedAttack(var/atom/A)
+/mob/living/simple_animal/slime/UnarmedAttack(atom/A)
A.attack_slime(src)
-/atom/proc/attack_slime(mob/user as mob)
+
+/atom/proc/attack_slime(mob/user)
return
-/mob/living/carbon/slime/RestrainedClickOn(var/atom/A)
+
+/mob/living/simple_animal/slime/RestrainedClickOn(atom/A)
return
/*
diff --git a/code/datums/components/decal.dm b/code/datums/components/decal.dm
index bdc1d3a2f6f..26d4653b25a 100644
--- a/code/datums/components/decal.dm
+++ b/code/datums/components/decal.dm
@@ -71,5 +71,5 @@
if(strength >= cleanable)
qdel(src)
-/datum/component/decal/proc/examine(datum/source, mob/user)
- to_chat(user, description)
\ No newline at end of file
+/datum/component/decal/proc/examine(datum/source, mob/user, var/list/examine_list)
+ examine_list += description
\ No newline at end of file
diff --git a/code/datums/components/ducttape.dm b/code/datums/components/ducttape.dm
index 5bbf99198fd..85568f7a09c 100644
--- a/code/datums/components/ducttape.dm
+++ b/code/datums/components/ducttape.dm
@@ -17,8 +17,8 @@
if(I.loc == user)
RT.Grant(user)
-/datum/component/proc/add_tape_text(datum/source, mob/user)
- to_chat(user, "There's some sticky tape attached to [source].")
+/datum/component/proc/add_tape_text(datum/source, mob/user, list/examine_list)
+ examine_list += "There's some sticky tape attached to [source]."
/datum/component/ducttape/proc/add_tape_overlay(obj/item/O)
tape_overlay = new('icons/obj/bureaucracy.dmi', "tape")
diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm
index 92c8c6b108d..8d44679fa4a 100644
--- a/code/datums/components/material_container.dm
+++ b/code/datums/components/material_container.dm
@@ -49,13 +49,13 @@
var/mat_path = possible_mats[id]
materials[id] = new mat_path()
-/datum/component/material_container/proc/OnExamine(datum/source, mob/user)
+/datum/component/material_container/proc/OnExamine(datum/source, mob/user, list/examine_list)
if(show_on_examine)
for(var/I in materials)
var/datum/material/M = materials[I]
var/amt = amount(M.id)
if(amt)
- to_chat(user, "It has [amt] units of [lowertext(M.name)] stored.")
+ examine_list += "It has [amt] units of [lowertext(M.name)] stored."
/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user)
var/list/tc = allowed_typecache
diff --git a/code/datums/diseases/advance/symptoms/damage_converter.dm b/code/datums/diseases/advance/symptoms/damage_converter.dm
index cba4d4a4cd0..8ee98df67ef 100644
--- a/code/datums/diseases/advance/symptoms/damage_converter.dm
+++ b/code/datums/diseases/advance/symptoms/damage_converter.dm
@@ -44,10 +44,11 @@ Bonus
if(!parts.len)
return
-
+ var/healed = 0
for(var/obj/item/organ/external/E in parts)
+ healed = min(E.brute_dam, get_damage) + min(E.burn_dam, get_damage)
E.heal_damage(get_damage, get_damage, 0, 0)
- M.adjustToxLoss(get_damage*parts.len)
+ M.adjustToxLoss(healed)
else
diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm
index 1378df4d05e..98b940f2b83 100644
--- a/code/datums/diseases/advance/symptoms/weight.dm
+++ b/code/datums/diseases/advance/symptoms/weight.dm
@@ -36,4 +36,4 @@ Bonus
else
to_chat(M, "[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]")
M.overeatduration = max(M.overeatduration - 100, 0)
- M.nutrition = max(M.nutrition - 100, 0)
\ No newline at end of file
+ M.adjust_nutrition(-100)
\ No newline at end of file
diff --git a/code/datums/diseases/food_poisoning.dm b/code/datums/diseases/food_poisoning.dm
index 2e7d083455b..4df31ec57d9 100644
--- a/code/datums/diseases/food_poisoning.dm
+++ b/code/datums/diseases/food_poisoning.dm
@@ -63,7 +63,7 @@
if(affected_mob.nutrition > 10)
affected_mob.visible_message("[affected_mob] vomits on the floor profusely!")
affected_mob.fakevomit(no_text = 1)
- affected_mob.nutrition -= rand(3,5)
+ affected_mob.adjust_nutrition(-rand(3,5))
else
to_chat(affected_mob, "Your stomach lurches painfully!")
affected_mob.visible_message("[affected_mob] gags and retches!")
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index 766c52c7b65..f619e9aa9bd 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -186,7 +186,7 @@
stage3 = list("Your appendages are melting away.", "Your limbs begin to lose their shape.")
stage4 = list("You are turning into a slime.")
stage5 = list("You have become a slime.")
- new_form = /mob/living/carbon/slime/random
+ new_form = /mob/living/simple_animal/slime/random
/datum/disease/transformation/slime/stage_act()
..()
diff --git a/code/datums/diseases/tuberculosis.dm b/code/datums/diseases/tuberculosis.dm
index 9aad7ff6d17..9a305c758e3 100644
--- a/code/datums/diseases/tuberculosis.dm
+++ b/code/datums/diseases/tuberculosis.dm
@@ -52,7 +52,7 @@
if(prob(3))
to_chat(affected_mob, "[pick("Your stomach silently rumbles...", "Your stomach seizes up and falls limp, muscles dead and lifeless.", "You could eat a crayon")]")
affected_mob.overeatduration = max(affected_mob.overeatduration - 100, 0)
- affected_mob.nutrition = max(affected_mob.nutrition - 100, 0)
+ affected_mob.adjust_nutrition(-100)
if(prob(15))
to_chat(affected_mob, "[pick("You feel uncomfortably hot...", "You feel like unzipping your jumpsuit", "You feel like taking off some clothes...")]")
affected_mob.bodytemperature += 40
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 65e188512d5..bb424a9afdf 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -140,6 +140,8 @@
var/mob/living/L = teleatom
if(L.buckled)
L.buckled.unbuckle_mob(L, force = TRUE)
+ if(L.has_buckled_mobs())
+ L.unbuckle_all_mobs(force = TRUE)
destarea.Entered(teleatom)
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index d03207ef41a..1a6bc4eb1c7 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -132,11 +132,17 @@
var/output = "[current.real_name]'s Memories:
"
output += memory
- if(objectives.len)
+ var/antag_datum_objectives = FALSE
+ for(var/datum/antagonist/A in antag_datums)
+ output += A.antag_memory
+ if(!antag_datum_objectives && LAZYLEN(A.objectives))
+ antag_datum_objectives = TRUE
+
+ if(LAZYLEN(objectives) || antag_datum_objectives)
output += "
Objectives:
"
output += gen_objective_text()
- if(job_objectives.len)
+ if(LAZYLEN(job_objectives))
output += "
Job Objectives:"
var/obj_count = 1
@@ -152,8 +158,16 @@
/datum/mind/proc/gen_objective_text(admin = FALSE)
. = ""
var/obj_count = 1
+ var/list/all_objectives = list()
+ for(var/datum/antagonist/A in antag_datums)
+ all_objectives |= A.objectives
+
+ if(LAZYLEN(all_objectives))
+ for(var/datum/objective/objective in all_objectives)
+ . += "
Objective #[obj_count++]: [objective.explanation_text]"
+
for(var/datum/objective/objective in objectives)
- . += "Objective #[obj_count]: [objective.explanation_text]"
+ . += "Objective #[obj_count++]: [objective.explanation_text]"
if(admin)
. += " Edit " // Edit
. += "Delete " // Delete
@@ -162,7 +176,6 @@
. += "Toggle Completion"
. += ""
. += "
"
- obj_count++
/datum/mind/proc/_memory_edit_header(gamemode, list/alt)
. = gamemode
@@ -327,14 +340,20 @@
/datum/mind/proc/memory_edit_traitor()
. = _memory_edit_header("traitor", list("traitorchan", "traitorvamp"))
- if(src in SSticker.mode.traitors)
+ if(has_antag_datum(/datum/antagonist/traitor))
. += "TRAITOR|no"
if(objectives.len==0)
- . += "
Objectives are empty! Randomize!"
+ . += "
Objectives are empty! Randomize!"
else
. += "traitor|NO"
. += _memory_edit_role_enabled(ROLE_TRAITOR)
+ // Mindslave
+ . += "
mindslaved: "
+ if(has_antag_datum(/datum/antagonist/mindslave))
+ . += "MINDSLAVE|no"
+ else
+ . += "mindslave|NO"
/datum/mind/proc/memory_edit_silicon()
. = "Silicon: "
@@ -352,7 +371,7 @@
/datum/mind/proc/memory_edit_uplink()
. = ""
if(ishuman(current) && ((src in SSticker.mode.head_revolutionaries) || \
- (src in SSticker.mode.traitors) || \
+ (has_antag_datum(/datum/antagonist/traitor)) || \
(src in SSticker.mode.syndicates)))
. = "Uplink: give"
var/obj/item/uplink/hidden/suplink = find_syndicate_uplink()
@@ -803,7 +822,8 @@
qdel(flash)
take_uplink()
var/fail = 0
- fail |= !SSticker.mode.equip_traitor(current, 1)
+ var/datum/antagonist/traitor/T = has_antag_datum(/datum/antagonist/traitor)
+ fail |= !T.equip_traitor(src)
fail |= !SSticker.mode.equip_revolutionary(current)
if(fail)
to_chat(usr, "Reequipping revolutionary goes wrong!")
@@ -1142,46 +1162,41 @@
else if(href_list["traitor"])
switch(href_list["traitor"])
if("clear")
- if(src in SSticker.mode.traitors)
- SSticker.mode.traitors -= src
- special_role = null
+ if(has_antag_datum(/datum/antagonist/traitor))
to_chat(current, "You have been brainwashed! You are no longer a traitor!")
+ remove_antag_datum(/datum/antagonist/traitor)
log_admin("[key_name(usr)] has de-traitored [key_name(current)]")
message_admins("[key_name_admin(usr)] has de-traitored [key_name_admin(current)]")
- if(isAI(current))
- var/mob/living/silicon/ai/A = current
- A.set_zeroth_law("")
- A.show_laws()
- A.verbs -= /mob/living/silicon/ai/proc/choose_modules
- A.malf_picker.remove_malf_verbs(A)
- qdel(A.malf_picker)
- SSticker.mode.update_traitor_icons_removed(src)
-
-
+
if("traitor")
- if(!(src in SSticker.mode.traitors))
- SSticker.mode.traitors += src
- var/datum/mindslaves/slaved = new()
- slaved.masters += src
- som = slaved //we MIGT want to mindslave someone
- special_role = SPECIAL_ROLE_TRAITOR
- to_chat(current, "You are a traitor!")
+ if(!(has_antag_datum(/datum/antagonist/traitor)))
+ var/datum/antagonist/traitor/T = new()
+ T.give_objectives = FALSE
+ T.should_equip = FALSE
+ add_antag_datum(T)
log_admin("[key_name(usr)] has traitored [key_name(current)]")
message_admins("[key_name_admin(usr)] has traitored [key_name_admin(current)]")
- if(isAI(current))
- var/mob/living/silicon/ai/A = current
- SSticker.mode.add_law_zero(A)
- SEND_SOUND(current, 'sound/ambience/antag/malf.ogg')
- else
- SEND_SOUND(current, 'sound/ambience/antag/tatoralert.ogg')
- SSticker.mode.update_traitor_icons_added(src)
if("autoobjectives")
- SSticker.mode.forge_traitor_objectives(src)
+ var/datum/antagonist/traitor/T = has_antag_datum(/datum/antagonist/traitor)
+ T.forge_traitor_objectives(src)
to_chat(usr, "The objectives for traitor [key] have been generated. You can edit them and announce manually.")
log_admin("[key_name(usr)] has automatically forged objectives for [key_name(current)]")
message_admins("[key_name_admin(usr)] has automatically forged objectives for [key_name_admin(current)]")
+ else if(href_list["mindslave"])
+ switch(href_list["mindslave"])
+ if("clear")
+ if(has_antag_datum(/datum/antagonist/mindslave))
+ var/mob/living/carbon/human/H = current
+ for(var/i in H.contents)
+ if(istype(i, /obj/item/implant/traitor))
+ qdel(i)
+ break
+ remove_antag_datum(/datum/antagonist/mindslave)
+ log_admin("[key_name(usr)] has de-mindslaved [key_name(current)]")
+ message_admins("[key_name_admin(usr)] has de-mindslaved [key_name_admin(current)]")
+
else if(href_list["shadowling"])
switch(href_list["shadowling"])
if("clear")
@@ -1251,17 +1266,20 @@
var/mob/living/silicon/robot/R = current
if(istype(R))
R.emagged = 0
- if(R.activated(R.module.emag))
- R.module_active = null
- if(R.module_state_1 == R.module.emag)
- R.module_state_1 = null
- R.contents -= R.module.emag
- else if(R.module_state_2 == R.module.emag)
- R.module_state_2 = null
- R.contents -= R.module.emag
- else if(R.module_state_3 == R.module.emag)
- R.module_state_3 = null
- R.contents -= R.module.emag
+ if(R.module)
+ if(R.activated(R.module.emag))
+ R.module_active = null
+ if(R.module_state_1 == R.module.emag)
+ R.module_state_1 = null
+ R.contents -= R.module.emag
+ else if(R.module_state_2 == R.module.emag)
+ R.module_state_2 = null
+ R.contents -= R.module.emag
+ else if(R.module_state_3 == R.module.emag)
+ R.module_state_3 = null
+ R.contents -= R.module.emag
+ R.clear_supplied_laws()
+ R.laws = new /datum/ai_laws/crewsimov
log_admin("[key_name(usr)] has un-emagged [key_name(current)]")
message_admins("[key_name_admin(usr)] has un-emagged [key_name_admin(current)]")
@@ -1282,6 +1300,8 @@
else if(R.module_state_3 == R.module.emag)
R.module_state_3 = null
R.contents -= R.module.emag
+ R.clear_supplied_laws()
+ R.laws = new /datum/ai_laws/crewsimov
log_admin("[key_name(usr)] has unemagged [key_name(ai)]'s cyborgs")
message_admins("[key_name_admin(usr)] has unemagged [key_name_admin(ai)]'s cyborgs")
@@ -1300,7 +1320,8 @@
message_admins("[key_name_admin(usr)] has unequipped [key_name_admin(current)]")
if("takeuplink")
take_uplink()
- memory = null//Remove any memory they may have had.
+ var/datum/antagonist/traitor/T = has_antag_datum(/datum/antagonist/traitor)
+ T.antag_memory = "" //Remove any antag memory they may have had (uplink codes, code phrases)
log_admin("[key_name(usr)] has taken [key_name(current)]'s uplink")
message_admins("[key_name_admin(usr)] has taken [key_name_admin(current)]'s uplink")
if("crystals")
@@ -1316,9 +1337,12 @@
log_admin("[key_name(usr)] has set [key_name(current)]'s telecrystals to [crystals]")
message_admins("[key_name_admin(usr)] has set [key_name_admin(current)]'s telecrystals to [crystals]")
if("uplink")
- if(!SSticker.mode.equip_traitor(current, !(src in SSticker.mode.traitors)))
- to_chat(usr, "Equipping a syndicate failed!")
- return
+ if(has_antag_datum(/datum/antagonist/traitor))
+ var/datum/antagonist/traitor/T = has_antag_datum(/datum/antagonist/traitor)
+ T.give_codewords()
+ if(!T.equip_traitor(src))
+ to_chat(usr, "Equipping a syndicate failed!")
+ return
log_admin("[key_name(usr)] has given [key_name(current)] an uplink")
message_admins("[key_name_admin(usr)] has given [key_name_admin(current)] an uplink")
@@ -1402,13 +1426,8 @@
qdel(H)
/datum/mind/proc/make_Traitor()
- if(!(src in SSticker.mode.traitors))
- SSticker.mode.traitors += src
- special_role = SPECIAL_ROLE_TRAITOR
- SSticker.mode.forge_traitor_objectives(src)
- SSticker.mode.finalize_traitor(src)
- SSticker.mode.greet_traitor(src)
- SSticker.mode.update_traitor_icons_added(src)
+ if(!has_antag_datum(/datum/antagonist/traitor))
+ add_antag_datum(/datum/antagonist/traitor)
/datum/mind/proc/make_Nuke()
if(!(src in SSticker.mode.syndicates))
@@ -1627,42 +1646,40 @@
if(G)
G.reenter_corpse()
+
/datum/mind/proc/make_zealot(mob/living/carbon/human/missionary, convert_duration = 6000, team_color = "red")
- if(!missionary || !istype(missionary)) //better provide a proper missionary or the rest of this is gonna break
- return 0
zealot_master = missionary
var/list/implanters
- var/ref = "\ref[missionary.mind]"
if(!(missionary.mind in SSticker.mode.implanter))
- SSticker.mode.implanter[ref] = list()
- implanters = SSticker.mode.implanter[ref]
+ SSticker.mode.implanter[missionary.mind] = list()
+ implanters = SSticker.mode.implanter[missionary.mind]
implanters.Add(src)
SSticker.mode.implanted.Add(src)
SSticker.mode.implanted[src] = missionary.mind
- //ticker.mode.implanter[missionary.mind] += src
- SSticker.mode.implanter[ref] = implanters
+ SSticker.mode.implanter[missionary.mind] = implanters
SSticker.mode.traitors += src
- special_role = "traitor"
+
+
+ var/datum/objective/protect/zealot_objective = new
+ zealot_objective.target = missionary.mind
+ zealot_objective.owner = src
+ zealot_objective.explanation_text = "Obey every order from and protect [missionary.real_name], the [missionary.mind.assigned_role == missionary.mind.special_role ? (missionary.mind.special_role) : (missionary.mind.assigned_role)]."
+ var/datum/antagonist/mindslave/S = new()
+ S.add_objective(zealot_objective)
+ add_antag_datum(S)
+
+ var/datum/antagonist/traitor/T = missionary.mind.has_antag_datum(/datum/antagonist)
+ T.update_traitor_icons_added(missionary.mind)
+
to_chat(current, "You're now a loyal zealot of [missionary.name]! You now must lay down your life to protect [missionary.p_them()] and assist in [missionary.p_their()] goals at any cost.")
- var/datum/objective/protect/mindslave/MS = new
- MS.owner = src
- MS.target = missionary.mind
- MS.explanation_text = "Obey every order from and protect [missionary.real_name], the [missionary.mind.assigned_role == missionary.mind.special_role ? (missionary.mind.special_role) : (missionary.mind.assigned_role)]."
- objectives += MS
- for(var/datum/objective/objective in objectives)
- to_chat(current, "Objective #1: [objective.explanation_text]")
- SSticker.mode.update_traitor_icons_added(missionary.mind)
- SSticker.mode.update_traitor_icons_added(src)//handles datahuds/observerhuds
-
- if(missionary.mind.som)//do not add if not a traitor..and you just picked up a robe and staff in the hall...
- var/datum/mindslaves/slaved = missionary.mind.som
- som = slaved
- slaved.serv += current
- slaved.add_serv_hud(missionary.mind, "master") //handles master servent icons
- slaved.add_serv_hud(src, "mindslave")
+ var/datum/mindslaves/slaved = missionary.mind.som
+ som = slaved
+ slaved.serv += current
+ slaved.add_serv_hud(missionary.mind, "master") //handles master servent icons
+ slaved.add_serv_hud(src, "mindslave")
var/obj/item/clothing/under/jumpsuit = null
if(ishuman(current)) //only bother with the jumpsuit stuff if we are a human type, since we won't have the slot otherwise
@@ -1679,7 +1696,7 @@
/datum/mind/proc/remove_zealot(obj/item/clothing/under/jumpsuit = null)
if(!zealot_master) //if they aren't a zealot, we can't remove their zealot status, obviously. don't bother with the rest so we don't confuse them with the messages
return
- SSticker.mode.remove_traitor_mind(src)
+ remove_antag_datum(/datum/antagonist/mindslave)
add_attack_logs(zealot_master, current, "Lost control of zealot")
zealot_master = null
@@ -1689,8 +1706,8 @@
var/mob/living/carbon/human/H = current
H.update_inv_w_uniform(0,0)
- to_chat(current, "You seem to have forgotten the events of the past 10 minutes or so, and your head aches a bit as if someone beat it savagely with a stick.")
- to_chat(current, "This means you don't remember who you were working for or what you were doing.")
+ to_chat(current, "You seem to have forgotten the events of the past 10 minutes or so, and your head aches a bit as if someone beat it savagely with a stick.")
+ to_chat(current, "This means you don't remember who you were working for or what you were doing.")
/datum/mind/proc/is_revivable() //Note, this ONLY checks the mind.
if(damnation_type)
@@ -1729,7 +1746,7 @@
mind.active = 1 //indicates that the mind is currently synced with a client
//slime
-/mob/living/carbon/slime/mind_initialize()
+/mob/living/simple_animal/slime/mind_initialize()
..()
mind.assigned_role = "slime"
@@ -1805,4 +1822,4 @@
/mob/living/simple_animal/construct/armoured/mind_initialize()
..()
mind.assigned_role = "Juggernaut"
- mind.special_role = SPECIAL_ROLE_CULTIST
\ No newline at end of file
+ mind.special_role = SPECIAL_ROLE_CULTIST
diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm
index ff8a93d3df0..93e4015233b 100644
--- a/code/datums/outfits/outfit_admin.dm
+++ b/code/datums/outfits/outfit_admin.dm
@@ -810,7 +810,7 @@
/datum/outfit/admin/hardsuit/wizard
name = "Wizard Hardsuit"
- suit = /obj/item/clothing/suit/space/hardsuit/wizard
+ suit = /obj/item/clothing/suit/space/hardsuit/shielded/wizard
shoes = /obj/item/clothing/shoes/magboots
/datum/outfit/admin/hardsuit/medical
@@ -1100,7 +1100,7 @@
l_hand = null
backpack_contents = list(
/obj/item/storage/box/engineer = 1,
- /obj/item/clothing/suit/space/hardsuit/wizard = 1,
+ /obj/item/clothing/suit/space/hardsuit/shielded/wizard = 1,
/obj/item/clothing/shoes/magboots = 1,
/obj/item/kitchen/knife/ritual = 1,
/obj/item/clothing/suit/wizrobe/red = 1,
diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm
index 023939c2747..2f07f106d2a 100644
--- a/code/datums/spells/area_teleport.dm
+++ b/code/datums/spells/area_teleport.dm
@@ -58,6 +58,9 @@
if(target && target.buckled)
target.buckled.unbuckle_mob(target, force = TRUE)
+ if(target && target.has_buckled_mobs())
+ target.unbuckle_all_mobs(force = TRUE)
+
var/list/tempL = L
var/attempt = null
var/success = 0
diff --git a/code/datums/spells/cluwne.dm b/code/datums/spells/cluwne.dm
index 09f98994f1e..6a87419886c 100644
--- a/code/datums/spells/cluwne.dm
+++ b/code/datums/spells/cluwne.dm
@@ -18,7 +18,7 @@
idiot_brain.insert(src, make_cluwne = 0)
idiot_brain.dna = dna.Clone()
setBrainLoss(80)
- nutrition = 9000
+ set_nutrition(9000)
overeatduration = 9000
Confused(30)
if(mind)
@@ -44,7 +44,7 @@
/mob/living/carbon/human/proc/makeAntiCluwne()
to_chat(src, "You don't feel very funny.")
adjustBrainLoss(-120)
- nutrition = NUTRITION_LEVEL_STARVING
+ set_nutrition(NUTRITION_LEVEL_STARVING)
overeatduration = 0
SetConfused(0)
SetJitter(0)
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index ff5ec99cd77..a5155cceb4a 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -234,7 +234,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/jobspecific/meatcleaver
name = "Meat Cleaver"
- desc = "A mean looking meat cleaver that does damage comparable to an Energy Sword but with the added benefit of chopping your victim into hunks of meat after they've died and the chance to stun when thrown."
+ desc = "A mean looking meat cleaver that does damage comparable to an Energy Sword but with the added benefit of chopping your victim into hunks of meat after they've died."
reference = "MC"
item = /obj/item/kitchen/knife/butcher/meatcleaver
cost = 10
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 375136796dc..15aeed4c291 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -277,7 +277,7 @@
//All atoms
-/atom/proc/examine(mob/user, var/distance = -1, var/infix = "", var/suffix = "")
+/atom/proc/examine(mob/user, infix = "", suffix = "")
//This reformat names to get a/an properly working on item descriptions when they are bloody
var/f_name = "\a [src][infix]."
if(src.blood_DNA && !istype(src, /obj/effect/decal))
@@ -289,33 +289,30 @@
f_name += "blood-stained [name][infix]!"
else
f_name += "oil-stained [name][infix]."
-
- to_chat(user, "[bicon(src)] That's [f_name] [suffix]")
+ . = list("[bicon(src)] That's [f_name] [suffix]")
if(desc)
- to_chat(user, desc)
+ . += desc
if(reagents)
if(container_type & TRANSPARENT)
- to_chat(user, "It contains:")
+ . += "It contains:"
if(reagents.reagent_list.len)
if(user.can_see_reagents()) //Show each individual reagent
for(var/I in reagents.reagent_list)
var/datum/reagent/R = I
- to_chat(user, "[R.volume] units of [R.name]")
+ . += "[R.volume] units of [R.name]"
else //Otherwise, just show the total volume
if(reagents && reagents.reagent_list.len)
- to_chat(user, "[reagents.total_volume] units of various reagents.")
+ . += "[reagents.total_volume] units of various reagents."
else
- to_chat(user, "Nothing. ")
+ . += "Nothing."
else if(container_type & AMOUNT_VISIBLE)
if(reagents.total_volume)
- to_chat(user, "It has [reagents.total_volume] unit\s left.")
+ . += "It has [reagents.total_volume] unit\s left."
else
- to_chat(user, "It's empty.")
+ . += "It's empty."
- SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user)
-
- return distance == -1 || (get_dist(src, user) <= distance) || isobserver(user) //observers do not have a range limit
+ SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
/atom/proc/relaymove()
return
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index 83102e528c4..b1e2f67da48 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -155,6 +155,9 @@
if(usr.abiotic())
to_chat(usr, "Subject cannot have abiotic items on.")
return
+ if(usr.has_buckled_mobs()) //mob attached to us
+ to_chat(usr, "[usr] will not fit into the [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head.")
+ return
usr.stop_pulling()
usr.forceMove(src)
src.occupant = usr
@@ -190,10 +193,9 @@
if(L.abiotic())
to_chat(user, "Subject cannot have abiotic items on.")
return
- for(var/mob/living/carbon/slime/M in range(1,L))
- if(M.Victim == L)
- to_chat(usr, "[L.name] will not fit into the [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")
- return
+ if(L.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")
+ return
if(L == user)
visible_message("[user] climbs into the [src].")
else
@@ -242,6 +244,9 @@
if(G.affecting.abiotic())
to_chat(user, "Subject cannot have abiotic items on.")
return
+ if(G.affecting.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "will not fit into the [src] because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.")
+ return
if(panel_open)
to_chat(usr, "Close the maintenance panel first.")
return
diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm
index 85e7126ae73..fa9f2a323e8 100644
--- a/code/game/dna/genes/goon_powers.dm
+++ b/code/game/dna/genes/goon_powers.dm
@@ -241,7 +241,7 @@
/mob/living/simple_animal/crab,
/mob/living/simple_animal/mouse,
/mob/living/carbon/human,
- /mob/living/carbon/slime,
+ /mob/living/simple_animal/slime,
/mob/living/carbon/alien/larva,
/mob/living/simple_animal/slime,
/mob/living/simple_animal/chick,
diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm
index 2137888d0b8..cc0cc307ed5 100644
--- a/code/game/gamemodes/autotraitor/autotraitor.dm
+++ b/code/game/gamemodes/autotraitor/autotraitor.dm
@@ -45,12 +45,12 @@
for(var/i = 0, i < num_traitors, i++)
var/datum/mind/traitor = pick(possible_traitors)
- traitors += traitor
+ pre_traitors += traitor
possible_traitors.Remove(traitor)
- for(var/datum/mind/traitor in traitors)
+ for(var/datum/mind/traitor in pre_traitors)
if(!traitor || !istype(traitor))
- traitors.Remove(traitor)
+ pre_traitors.Remove(traitor)
continue
if(istype(traitor))
traitor.special_role = SPECIAL_ROLE_TRAITOR
@@ -128,28 +128,8 @@
var/mob/living/newtraitor = newtraitormind.current
//message_admins("[newtraitor.real_name] is the new Traitor.")
- forge_traitor_objectives(newtraitor.mind)
-
- if(istype(newtraitor, /mob/living/silicon))
- SEND_SOUND(newtraitor, 'sound/ambience/antag/malf.ogg')
- add_law_zero(newtraitor)
- else
- SEND_SOUND(newtraitor, 'sound/ambience/antag/tatoralert.ogg')
- equip_traitor(newtraitor)
-
- traitors += newtraitor.mind
to_chat(newtraitor, "ATTENTION: It is time to pay your debt to the Syndicate...")
- to_chat(newtraitor, "You are now a traitor.")
- newtraitor.mind.special_role = SPECIAL_ROLE_TRAITOR
- var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_TRAITOR]
- tatorhud.join_hud(newtraitor)
- set_antag_hud(newtraitor, "hudsyndicate")
-
- var/obj_count = 1
- to_chat(newtraitor, "Your current objectives:")
- for(var/datum/objective/objective in newtraitor.mind.objectives)
- to_chat(newtraitor, "Objective #[obj_count]: [objective.explanation_text]")
- obj_count++
+ newtraitor.mind.add_antag_datum(/datum/antagonist/traitor)
//else
//message_admins("No new traitor being added.")
//else
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index 9bd6e54b069..dffbfd5290f 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -207,8 +207,8 @@
return
/obj/structure/blob/examine(mob/user)
- ..(user)
- to_chat(user, "It looks like it's made of [get_chem_name()].")
+ . = ..()
+ . += "It looks like it's made of [get_chem_name()]."
/obj/structure/blob/proc/get_chem_name()
diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm
index b5ad5ab9f8a..16251722632 100644
--- a/code/game/gamemodes/changeling/powers/absorb.dm
+++ b/code/game/gamemodes/changeling/powers/absorb.dm
@@ -58,7 +58,7 @@
changeling.absorb_dna(target, user)
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
- user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
+ user.set_nutrition(min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED))
if(target.mind)//if the victim has got a mind
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 2b3c0a538b5..74d7a1889e7 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -281,9 +281,9 @@
/obj/item/cult_shift/examine(mob/user)
. = ..()
if(uses)
- to_chat(user, "It has [uses] uses remaining.")
+ . += "It has [uses] uses remaining."
else
- to_chat(user, "It seems drained.")
+ . += "It seems drained."
/obj/item/cult_shift/proc/handle_teleport_grab(turf/T, mob/user)
var/mob/living/carbon/C = user
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index 81fadfc9470..9293bb94953 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -50,8 +50,8 @@
/obj/structure/cult/functional/examine(mob/user)
. = ..()
if(iscultist(user) && cooldowntime > world.time)
- to_chat(user, "The magic in [src] is weak, it will be ready to use again in [getETA()].")
- to_chat(user, "\The [src] is [anchored ? "":"not "]secured to the floor.")
+ . += "The magic in [src] is weak, it will be ready to use again in [getETA()]."
+ . += "\The [src] is [anchored ? "":"not "]secured to the floor."
/obj/structure/cult/functional/attackby(obj/I, mob/user, params)
if(HULK in user.mutations)
@@ -159,11 +159,13 @@
..()
var/list/blacklisted_pylon_turfs = typecacheof(list(
- /turf/simulated/floor/engine/cult,
- /turf/space,
- /turf/simulated/floor/plating/lava,
- /turf/simulated/floor/chasm,
- /turf/simulated/wall,
+ /turf/simulated/floor/engine/cult,
+ /turf/space,
+ /turf/simulated/floor/plating/lava,
+ /turf/simulated/floor/chasm,
+ /turf/simulated/wall/cult,
+ /turf/simulated/wall/cult/artificer,
+ /turf/unsimulated/wall
))
/obj/structure/cult/functional/pylon
@@ -223,7 +225,10 @@ var/list/blacklisted_pylon_turfs = typecacheof(list(
var/turf/T = safepick(validturfs)
if(T)
- T.ChangeTurf(/turf/simulated/floor/engine/cult)
+ if(istype(T, /turf/simulated/floor))
+ T.ChangeTurf(/turf/simulated/floor/engine/cult)
+ if(istype(T, /turf/simulated/wall))
+ T.ChangeTurf(/turf/simulated/wall/cult)
else
var/turf/simulated/floor/engine/cult/F = safepick(cultturfs)
if(F)
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index fb6bb95a4a8..24db67c952b 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -46,11 +46,11 @@
..()
/obj/item/tome/examine(mob/user)
- ..()
+ . = ..()
if(iscultist(user) || user.stat == DEAD)
- to_chat(user, "The scriptures of [SSticker.cultdat.entity_title3]. Allows the scribing of runes and access to the knowledge archives of the cult of [SSticker.cultdat.entity_name].")
- to_chat(user, "Striking another cultist with it will purge holy water from them.")
- to_chat(user, "Striking a noncultist, however, will sear their flesh.")
+ . += "The scriptures of [SSticker.cultdat.entity_title3]. Allows the scribing of runes and access to the knowledge archives of the cult of [SSticker.cultdat.entity_name]."
+ . += "Striking another cultist with it will purge holy water from them."
+ . += "Striking a noncultist, however, will sear their flesh."
/obj/item/tome/attack(mob/living/M, mob/living/user)
if(!istype(M))
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index d0b872ae006..5b34530f704 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -50,13 +50,13 @@ To draw a rune, use an arcane tome.
AI.client.images += blood
/obj/effect/rune/examine(mob/user)
- ..()
+ . = ..()
if(iscultist(user) || user.stat == DEAD) //If they're a cultist or a ghost, tell them the effects
- to_chat(user, "Name: [cultist_name]")
- to_chat(user, "Effects: [capitalize(cultist_desc)]")
- to_chat(user, "Required Acolytes: [req_cultists]")
+ . += "Name: [cultist_name]"
+ . += "Effects: [capitalize(cultist_desc)]"
+ . += "Required Acolytes: [req_cultists]"
if(req_keyword && keyword)
- to_chat(user, "Keyword: [keyword]")
+ . += "Keyword: [keyword]"
/obj/effect/rune/attackby(obj/I, mob/user, params)
if(istype(I, /obj/item/tome) && iscultist(user))
@@ -754,9 +754,9 @@ var/list/teleport_runes = list()
var/mob/living/affecting = null
/obj/effect/rune/astral/examine(mob/user)
- ..()
+ . = ..()
if(affecting)
- to_chat(user, "A translucent field encases [user] above the rune!")
+ . += "A translucent field encases [user] above the rune!"
/obj/effect/rune/astral/can_invoke(mob/living/user)
if(rune_in_use)
@@ -826,9 +826,9 @@ var/list/teleport_runes = list()
invoke_damage = 2
/obj/effect/rune/wall/examine(mob/user)
- ..()
+ . = ..()
if(density)
- to_chat(user, "There is a barely perceptible shimmering of the air above [src].")
+ . += "There is a barely perceptible shimmering of the air above [src]."
/obj/effect/rune/wall/invoke(var/list/invokers)
var/mob/living/user = invokers[1]
diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm
index 179425d320d..f7aaf2c1ebd 100644
--- a/code/game/gamemodes/cult/talisman.dm
+++ b/code/game/gamemodes/cult/talisman.dm
@@ -12,12 +12,13 @@
SEND_SIGNAL(src, COMSIG_OBJ_UPDATE_ICON)
/obj/item/paper/talisman/examine(mob/user)
+ . = ..()
if(iscultist(user) || user.stat == DEAD)
- to_chat(user, "Name: [cultist_name]")
- to_chat(user, "Effect: [cultist_desc]")
- to_chat(user, "Uses Remaining: [uses]")
+ . += "Name: [cultist_name]"
+ . += "Effect: [cultist_desc]"
+ . += "Uses Remaining: [uses]"
else
- to_chat(user, "You see strange symbols on the paper. Are they supposed to mean something?")
+ . += "You see strange symbols on the paper. Are they supposed to mean something?"
/obj/item/paper/talisman/attack_self(mob/living/user)
if(!iscultist(user))
diff --git a/code/game/gamemodes/devil/devilinfo.dm b/code/game/gamemodes/devil/devilinfo.dm
index 419034a9e1f..89d997831a3 100644
--- a/code/game/gamemodes/devil/devilinfo.dm
+++ b/code/game/gamemodes/devil/devilinfo.dm
@@ -162,7 +162,7 @@ var/global/list/lawlorify = list (
if(soulsOwned.Find(soul))
return
soulsOwned += soul
- owner.current.nutrition = NUTRITION_LEVEL_FULL
+ owner.current.set_nutrition(NUTRITION_LEVEL_FULL)
to_chat(owner.current, "You feel satiated as you received a new soul.")
update_hud()
switch(SOULVALUE)
diff --git a/code/game/gamemodes/devil/true_devil/_true_devil.dm b/code/game/gamemodes/devil/true_devil/_true_devil.dm
index 93b307f0105..197524c0e38 100644
--- a/code/game/gamemodes/devil/true_devil/_true_devil.dm
+++ b/code/game/gamemodes/devil/true_devil/_true_devil.dm
@@ -93,7 +93,7 @@
else if(health < (maxHealth/2))
msg += "You can see hellfire inside of it's wounds.\n"
msg += "*---------*"
- to_chat(user, msg)
+ . = list(msg)
/mob/living/carbon/true_devil/IsAdvancedToolUser()
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index efa1fd65498..fbbebc3acfc 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -563,16 +563,16 @@ Congratulations! You are now trained for invasive xenobiology research!"}
. = ..()
/obj/item/abductor_baton/examine(mob/user)
- ..()
+ . = ..()
switch(mode)
if(BATON_STUN)
- to_chat(user, "The baton is in stun mode.")
+ . += "The baton is in stun mode."
if(BATON_SLEEP)
- to_chat(user, "The baton is in sleep inducement mode.")
+ . += "The baton is in sleep inducement mode."
if(BATON_CUFF)
- to_chat(user, "The baton is in restraining mode.")
+ . += "The baton is in restraining mode."
if(BATON_PROBE)
- to_chat(user, "The baton is in probing mode.")
+ . += "The baton is in probing mode."
/obj/item/radio/headset/abductor
name = "alien headset"
diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm
index 2b0162829e1..2378ab1f789 100644
--- a/code/game/gamemodes/miniantags/abduction/gland.dm
+++ b/code/game/gamemodes/miniantags/abduction/gland.dm
@@ -129,7 +129,7 @@
to_chat(owner, "You feel nauseous!")
owner.vomit(20)
- var/mob/living/carbon/slime/Slime = new/mob/living/carbon/slime(get_turf(owner))
+ var/mob/living/simple_animal/slime/Slime = new(get_turf(owner), "grey")
Slime.Friends = list(owner)
Slime.Leader = owner
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
index db6f07c1d24..fd7e7892cd4 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
@@ -27,10 +27,9 @@
return //occupied
if(target.buckled)
return
- for(var/mob/living/carbon/slime/M in range(1, target))
- if(M.Victim == target)
- to_chat(user, "[target] has a slime attached to [target.p_them()], deal with that first.")
- return
+ if(target.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[target] will not fit into [src] because [target.p_they()] [target.p_have()] a slime latched onto [target.p_their()] head.")
+ return
visible_message("[user] puts [target] into the [src].")
target.forceMove(src)
@@ -191,10 +190,9 @@
if(occupant)
to_chat(user, "The [src] is already occupied!")
return
- for(var/mob/living/carbon/slime/S in range(1, grabbed.affecting))
- if(S.Victim == grabbed.affecting)
- to_chat(user, "[grabbed.affecting] has a slime attached to them, deal with that first.")
- return
+ if(grabbed.affecting.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[grabbed.affecting] will not fit into [src] because [grabbed.affecting.p_they()] [grabbed.affecting.p_have()] a slime latched onto [grabbed.affecting.p_their()] head.")
+ return
visible_message("[user] puts [grabbed.affecting] into the [src].")
var/mob/living/carbon/human/H = grabbed.affecting
H.forceMove(src)
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index 6d1820ad54e..757b4722927 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -355,7 +355,7 @@
S.DisperseTarget(src)
return TRUE
-/mob/living/carbon/slime/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+/mob/living/simple_animal/slime/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
to_chat(S, "This biological resource is somehow resisting our bluespace transceiver. Aborting.")
return FALSE
diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm
index fc7fcce72e0..17d7187f439 100644
--- a/code/game/gamemodes/miniantags/guardian/guardian.dm
+++ b/code/game/gamemodes/miniantags/guardian/guardian.dm
@@ -73,7 +73,8 @@
qdel()
/mob/living/simple_animal/hostile/guardian/proc/snapback()
- if(summoner)
+ // If the summoner dies instantly, the summoner's ghost may be drawn into null space as the protector is deleted. This check should prevent that.
+ if(summoner && loc && summoner.loc)
if(get_dist(get_turf(summoner),get_turf(src)) <= range)
return
else
@@ -309,7 +310,7 @@
/obj/item/guardiancreator/examine(mob/user, distance)
. = ..()
if(used)
- to_chat(user, "[used_message]")
+ . += "[used_message]"
/obj/item/guardiancreator/proc/spawn_guardian(mob/living/user, key)
var/guardian_type = "Standard"
diff --git a/code/game/gamemodes/miniantags/guardian/types/bomb.dm b/code/game/gamemodes/miniantags/guardian/types/bomb.dm
index fbe4458693f..b69487644f0 100644
--- a/code/game/gamemodes/miniantags/guardian/types/bomb.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/bomb.dm
@@ -82,6 +82,6 @@
return FALSE // Disarm or blow up. No picking up
/obj/item/guardian_bomb/examine(mob/user)
- stored_obj.examine(user)
- if(get_dist(user,src) <= 2)
- to_chat(user, "Looks odd!")
+ . = stored_obj.examine(user)
+ if(get_dist(user, src) <= 2)
+ . += "Looks odd!"
diff --git a/code/game/gamemodes/miniantags/guardian/types/protector.dm b/code/game/gamemodes/miniantags/guardian/types/protector.dm
index 9206b0d1b0b..5fb31b8ba15 100644
--- a/code/game/gamemodes/miniantags/guardian/types/protector.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/protector.dm
@@ -41,7 +41,8 @@
toggle = TRUE
/mob/living/simple_animal/hostile/guardian/protector/snapback() //snap to what? snap to the guardian!
- if(summoner)
+ // If the summoner dies instantly, the summoner's ghost may be drawn into null space as the protector is deleted. This check should prevent that.
+ if(summoner && loc && summoner.loc)
if(get_dist(get_turf(summoner),get_turf(src)) <= range)
return
else
diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm
index 1da936b64ee..ef90f44f4a0 100644
--- a/code/game/gamemodes/miniantags/morph/morph.dm
+++ b/code/game/gamemodes/miniantags/morph/morph.dm
@@ -38,6 +38,8 @@
var/atom/movable/form = null
var/morph_time = 0
+ var/list/examine_text_list
+
var/playstyle_string = "You are a morph.
As an abomination created primarily with changeling cells, \
you may take the form of anything nearby by shift-clicking it. This process will alert any nearby \
observers, and can only be performed once every five seconds.
While morphed, you move faster, but do \
@@ -57,16 +59,11 @@
/mob/living/simple_animal/hostile/morph/examine(mob/user)
if(morphed)
- if(form)
- form.examine(user) // Refactor examine to return desc so it's static? Not sure if worth it
- // If the object you've disguised as has been deleted, your cover's probably blown
- else
- ..()
- if(get_dist(user,src)<=3)
- to_chat(user, "It doesn't look quite right...")
+ . = examine_text_list.Copy()
+ if(get_dist(user, src) <= 3)
+ . += "It doesn't look quite right..."
else
- ..()
- return
+ . = ..()
/mob/living/simple_animal/hostile/morph/proc/allowed(atom/movable/A) // make it into property/proc ? not sure if worth it
if(istype(A,/obj/screen))
@@ -109,7 +106,7 @@
melee_damage_lower = 5
melee_damage_upper = 5
speed = 0
-
+ examine_text_list = form.examine(src)
morph_time = world.time + MORPH_COOLDOWN
return
@@ -118,7 +115,7 @@
return
morphed = 0
form = null
-
+ examine_text_list = null // Free that memory
visible_message("[src] suddenly collapses in on itself, dissolving into a pile of green flesh!", \
"You reform to your normal body.")
name = initial(name)
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index 1030a1407b3..b761af6db92 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -374,11 +374,11 @@
qdel(src)
/obj/item/ectoplasm/revenant/examine(mob/user)
- ..(user)
+ . = ..()
if(inert)
- to_chat(user, "It seems inert.")
+ . += "It seems inert."
else if(reforming)
- to_chat(user, "It is shifting and distorted. It would be wise to destroy this.")
+ . += "It is shifting and distorted. It would be wise to destroy this."
/obj/item/ectoplasm/revenant/proc/reform()
if(inert || !src)
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index b6ec5cb74a5..251c32716bb 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -78,13 +78,11 @@
.()
/obj/item/pinpointer/examine(mob/user)
- ..(user)
- if(!shows_nuke_timer)
- return
-
- for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
- if(bomb.timing)
- to_chat(user, "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]")
+ . = ..()
+ if(shows_nuke_timer)
+ for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
+ if(bomb.timing)
+ . += "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]"
/obj/item/pinpointer/advpinpointer
name = "advanced pinpointer"
@@ -311,12 +309,12 @@
return 0
/obj/item/pinpointer/operative/examine(mob/user)
- ..()
+ . = ..()
if(active)
if(nearest_op)
- to_chat(user, "Nearest operative detected is [nearest_op.real_name].")
+ . += "Nearest operative detected is [nearest_op.real_name]."
else
- to_chat(user, "No operatives detected within scanning range.")
+ . += "No operatives detected within scanning range."
/obj/item/pinpointer/crew
name = "crew pinpointer"
@@ -396,9 +394,6 @@
spawn(5)
.()
-/obj/item/pinpointer/crew/examine(mob/user)
- ..(user)
-
/obj/item/pinpointer/crew/centcom
name = "centcom pinpointer"
desc = "A handheld tracking device that tracks crew based on remote centcom sensors."
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 42ebb351e42..214c349978a 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -63,6 +63,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
explanation_text = "Assassinate [target.current.real_name], the [target.assigned_role]."
else
explanation_text = "Free Objective"
+ return target
/datum/objective/assassinate/check_completion()
if(target && target.current)
@@ -506,6 +507,54 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
return 0
return 1
+/datum/objective/steal_five_of_type
+ explanation_text = "Steal at least five items!"
+ var/list/wanted_items = list()
+
+/datum/objective/steal_five_of_type/New()
+ ..()
+ wanted_items = typecacheof(wanted_items)
+
+/datum/objective/steal_five_of_type/check_completion()
+ var/stolen_count = 0
+ if(!isliving(owner.current))
+ return FALSE
+ var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc.
+ for(var/obj/I in all_items) //Check for wanted items
+ if(is_type_in_typecache(I, wanted_items))
+ stolen_count++
+ return stolen_count >= 5
+
+/datum/objective/steal_five_of_type/summon_guns
+ explanation_text = "Steal at least five guns!"
+ wanted_items = list(/obj/item/gun)
+
+/datum/objective/steal_five_of_type/summon_magic
+ explanation_text = "Steal at least five magical artefacts!"
+ wanted_items = list()
+
+/datum/objective/steal_five_of_type/summon_magic/New()
+ wanted_items = GLOB.summoned_magic_objectives
+ ..()
+
+/datum/objective/steal_five_of_type/summon_magic/check_completion()
+ var/stolen_count = 0
+ if(!isliving(owner.current))
+ return FALSE
+ var/list/all_items = owner.current.GetAllContents() //this should get things in cheesewheels, books, etc.
+ for(var/obj/I in all_items) //Check for wanted items
+ if(istype(I, /obj/item/spellbook) && !istype(I, /obj/item/spellbook/oneuse))
+ var/obj/item/spellbook/spellbook = I
+ if(spellbook.uses) //if the book still has powers...
+ stolen_count++ //it counts. nice.
+ if(istype(I, /obj/item/spellbook/oneuse))
+ var/obj/item/spellbook/oneuse/oneuse = I
+ if(!oneuse.used)
+ stolen_count++
+ else if(is_type_in_typecache(I, wanted_items))
+ stolen_count++
+ return stolen_count >= 5
+
/datum/objective/blood
/datum/objective/blood/proc/gen_amount_goal(low = 150, high = 400)
target_amount = rand(low,high)
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 408c5fa1de9..ae131286afd 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -16,9 +16,10 @@
required_enemies = 1
recommended_enemies = 4
+ var/list/datum/mind/pre_traitors = list()
var/traitors_possible = 4 //hard limit on traitors if scaling is turned off
var/const/traitor_scaling_coeff = 5.0 //how much does the amount of players get divided by to determine traitors
-
+ var/antag_datum = /datum/antagonist/traitor //what type of antag to create
/datum/game_mode/traitor/announce()
to_chat(world, "The current game mode is - Traitor!")
@@ -47,158 +48,24 @@
if(!possible_traitors.len)
break
var/datum/mind/traitor = pick(possible_traitors)
- traitors += traitor
+ pre_traitors += traitor
traitor.special_role = SPECIAL_ROLE_TRAITOR
- var/datum/mindslaves/slaved = new()
- slaved.masters += traitor
- traitor.som = slaved //we MIGT want to mindslave someone
traitor.restricted_roles = restricted_jobs
possible_traitors.Remove(traitor)
- if(!traitors.len)
+ if(!pre_traitors.len)
return 0
return 1
/datum/game_mode/traitor/post_setup()
- for(var/datum/mind/traitor in traitors)
- forge_traitor_objectives(traitor)
- update_traitor_icons_added(traitor)
- spawn(rand(10,100))
- finalize_traitor(traitor)
- greet_traitor(traitor)
- modePlayer += traitors
+ for(var/datum/mind/traitor in pre_traitors)
+ var/datum/antagonist/traitor/new_antag = new antag_datum()
+ addtimer(CALLBACK(traitor, /datum/mind.proc/add_antag_datum, new_antag), rand(10,100))
+ if(!exchange_blue)
+ exchange_blue = -1 //Block latejoiners from getting exchange objectives
..()
-/datum/game_mode/proc/forge_traitor_objectives(datum/mind/traitor)
- if(istype(traitor.current, /mob/living/silicon))
- var/objective_count = 0
-
- if(prob(30))
- var/special_pick = rand(1,2)
- switch(special_pick)
- if(1)
- var/datum/objective/block/block_objective = new
- block_objective.owner = traitor
- traitor.objectives += block_objective
- objective_count++
- if(2) //Protect and strand a target
- var/datum/objective/protect/yandere_one = new
- yandere_one.owner = traitor
- traitor.objectives += yandere_one
- yandere_one.find_target()
- traitor.targets += yandere_one.target
- objective_count++
- var/datum/objective/maroon/yandere_two = new
- yandere_two.owner = traitor
- yandere_two.target = yandere_one.target
- traitor.objectives += yandere_two
- objective_count++
-
- for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = traitor
- kill_objective.find_target()
- traitor.objectives += kill_objective
- traitor.targets += kill_objective.target
-
- var/datum/objective/survive/survive_objective = new
- survive_objective.owner = traitor
- traitor.objectives += survive_objective
-
- else
- var/is_hijacker = prob(10)
- var/martyr_chance = prob(20)
- var/objective_count = is_hijacker //Hijacking counts towards number of objectives
- if(!exchange_blue && traitors.len >= 8) //Set up an exchange if there are enough traitors
- if(!exchange_red)
- exchange_red = traitor
- else
- exchange_blue = traitor
- assign_exchange_role(exchange_red)
- assign_exchange_role(exchange_blue)
- var/list/active_ais = active_ais()
- for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
- if(prob(50))
- if(active_ais.len && prob(100/GLOB.player_list.len))
- var/datum/objective/destroy/destroy_objective = new
- destroy_objective.owner = traitor
- destroy_objective.find_target()
- traitor.objectives += destroy_objective
- traitor.targets += destroy_objective.target
- else if(prob(5))
- var/datum/objective/debrain/debrain_objective = new
- debrain_objective.owner = traitor
- debrain_objective.find_target()
- traitor.objectives += debrain_objective
- traitor.targets += debrain_objective.target
- else if(prob(30))
- var/datum/objective/maroon/maroon_objective = new
- maroon_objective.owner = traitor
- maroon_objective.find_target()
- traitor.objectives += maroon_objective
- traitor.targets += maroon_objective.target
- else
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = traitor
- kill_objective.find_target()
- traitor.objectives += kill_objective
- traitor.targets += kill_objective.target
- else
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = traitor
- steal_objective.find_target()
- traitor.objectives += steal_objective
- traitor.targets += steal_objective.steal_target
-
- if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
- if(!(locate(/datum/objective/hijack) in traitor.objectives))
- var/datum/objective/hijack/hijack_objective = new
- hijack_objective.owner = traitor
- traitor.objectives += hijack_objective
- return
-
-
- var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead.
- for(var/datum/objective/O in traitor.objectives)
- if(!O.martyr_compatible)
- martyr_compatibility = 0
- break
-
- if(martyr_compatibility && martyr_chance)
- var/datum/objective/die/martyr_objective = new
- martyr_objective.owner = traitor
- traitor.objectives += martyr_objective
- return
-
- else
- if(!(locate(/datum/objective/escape) in traitor.objectives))
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = traitor
- traitor.objectives += escape_objective
- return
-
-
-/datum/game_mode/proc/greet_traitor(var/datum/mind/traitor)
- if(istype(traitor.current, /mob/living/silicon))
- SEND_SOUND(traitor.current, 'sound/ambience/antag/malf.ogg')
- else
- SEND_SOUND(traitor.current, 'sound/ambience/antag/tatoralert.ogg')
- to_chat(traitor.current, "You are the traitor.")
- var/obj_count = 1
- for(var/datum/objective/objective in traitor.objectives)
- to_chat(traitor.current, "Objective #[obj_count]: [objective.explanation_text]")
- obj_count++
- return
-
-
-/datum/game_mode/proc/finalize_traitor(var/datum/mind/traitor)
- if(istype(traitor.current, /mob/living/silicon))
- add_law_zero(traitor.current)
- else
- equip_traitor(traitor.current)
- return
-
/datum/game_mode/traitor/declare_completion()
..()
@@ -212,28 +79,6 @@
objective.check_completion()
return 0
-/datum/game_mode/proc/give_codewords(mob/living/traitor_mob)
- to_chat(traitor_mob, "The Syndicate provided you with the following information on how to identify their agents:")
- to_chat(traitor_mob, "Code Phrase: [GLOB.syndicate_code_phrase]")
- to_chat(traitor_mob, "Code Response: [GLOB.syndicate_code_response]")
-
- traitor_mob.mind.store_memory("Code Phrase: [GLOB.syndicate_code_phrase]")
- traitor_mob.mind.store_memory("Code Response: [GLOB.syndicate_code_response]")
-
- to_chat(traitor_mob, "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe.")
-
-/datum/game_mode/proc/add_law_zero(mob/living/silicon/ai/killer)
- var/law = "Accomplish your objectives at all costs."
- var/law_borg = "Accomplish your AI's objectives at all costs."
- to_chat(killer, "Your laws have been changed!")
- killer.set_zeroth_law(law, law_borg)
- to_chat(killer, "New law: 0. [law]")
- give_codewords(killer)
- killer.set_syndie_radio()
- to_chat(killer, "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!")
- killer.verbs += /mob/living/silicon/ai/proc/choose_modules
- killer.malf_picker = new /datum/module_picker
-
/datum/game_mode/proc/auto_declare_completion_traitor()
if(traitors.len)
@@ -292,149 +137,11 @@
text += "
The [special_role_text] has failed!"
feedback_add_details("traitor_success","FAIL")
+ var/phrases = jointext(GLOB.syndicate_code_phrase, ", ")
+ var/responses = jointext(GLOB.syndicate_code_response, ", ")
+
+ text += "
The code phrases were: [phrases]
\
+ The code responses were: [responses]
"
to_chat(world, text)
return 1
-
-
-/datum/game_mode/proc/equip_traitor(mob/living/carbon/human/traitor_mob, var/safety = 0)
- if(!istype(traitor_mob))
- return
- . = 1
- if(traitor_mob.mind)
- if(traitor_mob.mind.assigned_role == "Clown")
- to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
- traitor_mob.mutations.Remove(CLUMSY)
- var/datum/action/innate/toggle_clumsy/A = new
- A.Grant(traitor_mob)
-
-
- // find a radio! toolbox(es), backpack, belt, headset
- var/obj/item/R = locate(/obj/item/pda) in traitor_mob.contents //Hide the uplink in a PDA if available, otherwise radio
- if(!R)
- R = locate(/obj/item/radio) in traitor_mob.contents
-
- if(!R)
- to_chat(traitor_mob, "Unfortunately, the Syndicate wasn't able to get you a radio.")
- . = 0
- else
- if(istype(R, /obj/item/radio))
- // generate list of radio freqs
- var/obj/item/radio/target_radio = R
- var/freq = PUBLIC_LOW_FREQ
- var/list/freqlist = list()
- while(freq <= PUBLIC_HIGH_FREQ)
- if(freq < 1451 || freq > 1459)
- freqlist += freq
- freq += 2
- if((freq % 2) == 0)
- freq += 1
- freq = freqlist[rand(1, freqlist.len)]
-
- var/obj/item/uplink/hidden/T = new(R)
- target_radio.hidden_uplink = T
- T.uplink_owner = "[traitor_mob.key]"
- target_radio.traitor_frequency = freq
- to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [R.name] [T.loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features.")
- traitor_mob.mind.store_memory("Radio Freq: [format_frequency(freq)] ([R.name] [T.loc]).")
- else if(istype(R, /obj/item/pda))
- // generate a passcode if the uplink is hidden in a PDA
- var/pda_pass = "[rand(100,999)] [pick("Alpha","Bravo","Delta","Omega")]"
-
- var/obj/item/uplink/hidden/T = new(R)
- R.hidden_uplink = T
- T.uplink_owner = "[traitor_mob.key]"
- var/obj/item/pda/P = R
- P.lock_code = pda_pass
-
- to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [R.name] [T.loc]. Simply enter the code \"[pda_pass]\" into the ringtone select to unlock its hidden features.")
- traitor_mob.mind.store_memory("Uplink Passcode: [pda_pass] ([R.name] [T.loc]).")
- if(!safety)//If they are not a rev. Can be added on to.
- give_codewords(traitor_mob)
-
-/datum/game_mode/proc/remove_traitor(datum/mind/traitor_mind)
- if(traitor_mind in traitors)
- SSticker.mode.traitors -= traitor_mind
- traitor_mind.special_role = null
- traitor_mind.current.create_attack_log("De-traitored")
- if(issilicon(traitor_mind.current))
- to_chat(traitor_mind.current, "You have been turned into a robot! You are no longer a traitor.")
- else
- to_chat(traitor_mind.current, "You have been brainwashed! You are no longer a traitor.")
- SSticker.mode.update_traitor_icons_removed(traitor_mind)
-
-/datum/game_mode/proc/update_traitor_icons_added(datum/mind/traitor_mind)
- var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_TRAITOR]
- tatorhud.join_hud(traitor_mind.current)
- set_antag_hud(traitor_mind.current, "hudsyndicate")
-
-/datum/game_mode/proc/update_traitor_icons_removed(datum/mind/traitor_mind)
- var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_TRAITOR]
- tatorhud.leave_hud(traitor_mind.current)
- set_antag_hud(traitor_mind.current, null)
-
-
-/datum/game_mode/proc/remove_traitor_mind(datum/mind/traitor_mind, datum/mind/head)
- if(traitor_mind in implanted)
- //var/list/removal
- var/ref = "\ref[head]"
- if(ref in implanter)
- implanter[ref] -= traitor_mind
- implanted -= traitor_mind
- traitors -= traitor_mind
- if(traitor_mind.som)
- var/datum/mindslaves/slaved = traitor_mind.som
- slaved.serv -= traitor_mind
- traitor_mind.special_role = null
- traitor_mind.som = null
- slaved.leave_serv_hud(traitor_mind)
- for(var/datum/objective/protect/mindslave/MS in traitor_mind.objectives)
- traitor_mind.objectives -= MS
-
- update_traitor_icons_removed(traitor_mind)
- if(issilicon(traitor_mind.current))
- to_chat(traitor_mind.current, "You have been turned into a robot! You are no longer a mindslave.")
- else
- to_chat(traitor_mind.current, "You are no longer a mindslave: you have complete and free control of your own faculties, once more!")
-
-/datum/game_mode/proc/assign_exchange_role(var/datum/mind/owner)
- //set faction
- var/faction = "red"
- if(owner == exchange_blue)
- faction = "blue"
-
- //Assign objectives
- var/datum/objective/steal/exchange/exchange_objective = new
- exchange_objective.set_faction(faction,((faction == "red") ? exchange_blue : exchange_red))
- exchange_objective.owner = owner
- owner.objectives += exchange_objective
-
- if(prob(20))
- var/datum/objective/steal/exchange/backstab/backstab_objective = new
- backstab_objective.set_faction(faction)
- backstab_objective.owner = owner
- owner.objectives += backstab_objective
-
- //Spawn and equip documents
- var/mob/living/carbon/human/mob = owner.current
-
- var/obj/item/folder/syndicate/folder
- if(owner == exchange_red)
- folder = new/obj/item/folder/syndicate/red(mob.locs)
- else
- folder = new/obj/item/folder/syndicate/blue(mob.locs)
-
- var/list/slots = list (
- "backpack" = slot_in_backpack,
- "left pocket" = slot_l_store,
- "right pocket" = slot_r_store,
- "left hand" = slot_l_hand,
- "right hand" = slot_r_hand,
- )
-
- var/where = "At your feet"
- var/equipped_slot = mob.equip_in_one_of_slots(folder, slots)
- if(equipped_slot)
- where = "In your [equipped_slot]"
- to_chat(mob, "
[where] is a folder containing secret documents that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile.
")
- mob.update_icons()
diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm
index d696543cbdf..ac5ddc92f98 100644
--- a/code/game/gamemodes/vampire/vampire.dm
+++ b/code/game/gamemodes/vampire/vampire.dm
@@ -314,9 +314,9 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
var/mob/living/carbon/human/V = owner
if(!H.ckey && !H.player_ghosted)//Only runs if there is no ckey and the body has not being ghosted while alive
to_chat(V, "Feeding on [H] reduces your thirst, but you get no usable blood from them.")
- V.nutrition = min(NUTRITION_LEVEL_WELL_FED, V.nutrition + 5)
+ V.set_nutrition(min(NUTRITION_LEVEL_WELL_FED, V.nutrition + 5))
else
- V.nutrition = min(NUTRITION_LEVEL_WELL_FED, V.nutrition + (blood / 2))
+ V.set_nutrition(min(NUTRITION_LEVEL_WELL_FED, V.nutrition + (blood / 2)))
draining = null
diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm
index e69a4b7ec79..5f2dc094724 100644
--- a/code/game/gamemodes/wizard/rightandwrong.dm
+++ b/code/game/gamemodes/wizard/rightandwrong.dm
@@ -1,170 +1,169 @@
+//In this file: Summon Magic/Summon Guns/Summon Events
+// 1 in 50 chance of getting something really special.
+#define SPECIALIST_MAGIC_PROB 2
-/mob/proc/rightandwrong(summon_type, revolver_fight = FALSE, fake_revolver_fight = FALSE) //0 = Summon Guns, 1 = Summon Magic
- var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","arg","uzi","turret","pulsecarbine","decloner","mindflayer","kinetic","advplasmacutter","wormhole","wt550","grenadelauncher","medibeam", "fakerevolver")
- var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffhealing", "armor", "scrying", "staffdoor", "special","voodoo","special")
- var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos","necromantic")
+GLOBAL_LIST_INIT(summoned_guns, list(
+ /obj/item/gun/energy/disabler,
+ /obj/item/gun/energy/gun,
+ /obj/item/gun/energy/gun/advtaser,
+ /obj/item/gun/energy/laser,
+ /obj/item/gun/projectile/revolver,
+ /obj/item/gun/projectile/revolver/detective,
+ /obj/item/gun/projectile/automatic/pistol/deagle/camo,
+ /obj/item/gun/projectile/automatic/gyropistol,
+ /obj/item/gun/energy/pulse,
+ /obj/item/gun/projectile/automatic/pistol,
+ /obj/item/gun/projectile/revolver/doublebarrel,
+ /obj/item/gun/projectile/shotgun,
+ /obj/item/gun/projectile/shotgun/automatic/combat,
+ /obj/item/gun/projectile/automatic/ar,
+ /obj/item/gun/projectile/revolver/mateba,
+ /obj/item/gun/projectile/shotgun/boltaction,
+ /obj/item/gun/projectile/automatic/mini_uzi,
+ /obj/item/gun/energy/lasercannon,
+ /obj/item/gun/energy/kinetic_accelerator/crossbow/large,
+ /obj/item/gun/energy/gun/nuclear,
+ /obj/item/gun/projectile/automatic/proto,
+ /obj/item/gun/projectile/automatic/c20r,
+ /obj/item/gun/projectile/automatic/l6_saw,
+ /obj/item/gun/projectile/automatic/m90,
+ /obj/item/gun/energy/alien,
+ /obj/item/gun/energy/gun/turret,
+ /obj/item/gun/energy/pulse/carbine,
+ /obj/item/gun/energy/decloner,
+ /obj/item/gun/energy/mindflayer,
+ /obj/item/gun/energy/kinetic_accelerator,
+ /obj/item/gun/energy/plasmacutter/adv,
+ /obj/item/gun/energy/wormhole_projector,
+ /obj/item/gun/projectile/automatic/wt550,
+ /obj/item/gun/projectile/automatic/shotgun/bulldog,
+ /obj/item/gun/projectile/revolver/grenadelauncher,
+ /obj/item/gun/projectile/revolver/golden,
+ /obj/item/gun/projectile/automatic/sniper_rifle,
+ /obj/item/gun/medbeam,
+ /obj/item/gun/energy/laser/scatter))
- to_chat(usr, "You summoned [summon_type ? "magic" : "guns"]!")
- message_admins("[key_name_admin(usr)] summoned [summon_type ? "magic" : "guns"]! ([revolver_fight ? "Revolver duel!" : ""] [fake_revolver_fight ? "Suicidal revolver duel!" : ""])")
+//if you add anything that isn't covered by the typepaths below, add it to summon_magic_objective_types
+GLOBAL_LIST_INIT(summoned_magic, list(
+ /obj/item/spellbook/oneuse/fireball,
+ /obj/item/spellbook/oneuse/smoke,
+ /obj/item/spellbook/oneuse/blind,
+ /obj/item/spellbook/oneuse/mindswap,
+ /obj/item/spellbook/oneuse/forcewall,
+ /obj/item/spellbook/oneuse/knock,
+ /obj/item/spellbook/oneuse/horsemask,
+ /obj/item/spellbook/oneuse/charge,
+ /obj/item/spellbook/oneuse/summonitem,
+ /obj/item/gun/magic/wand,
+ /obj/item/gun/magic/wand/death,
+ /obj/item/gun/magic/wand/resurrection,
+ /obj/item/gun/magic/wand/polymorph,
+ /obj/item/gun/magic/wand/teleport,
+ /obj/item/gun/magic/wand/door,
+ /obj/item/gun/magic/wand/fireball,
+ /obj/item/gun/magic/staff/healing,
+ /obj/item/gun/magic/staff/door,
+ /obj/item/scrying,
+ /obj/item/voodoo,
+ /obj/item/clothing/suit/space/hardsuit/shielded/wizard,
+ /obj/item/immortality_talisman,
+ /obj/item/melee/ghost_sword))
+
+GLOBAL_LIST_INIT(summoned_special_magic, list(
+ /obj/item/gun/magic/staff/change,
+ /obj/item/gun/magic/staff/animate,
+ /obj/item/storage/belt/wands/full,
+ /obj/item/contract,
+ /obj/item/gun/magic/staff/chaos,
+ /obj/item/necromantic_stone,
+ /obj/item/blood_contract))
+
+//everything above except for single use spellbooks, because they are counted separately (and are for basic bitches anyways)
+GLOBAL_LIST_INIT(summoned_magic_objectives, list(
+ /obj/item/contract,
+ /obj/item/blood_contract,
+ /obj/item/clothing/suit/space/hardsuit/shielded/wizard,
+ /obj/item/gun/magic,
+ /obj/item/immortality_talisman,
+ /obj/item/melee/ghost_sword,
+ /obj/item/necromantic_stone,
+ /obj/item/scrying,
+ /obj/item/spellbook,
+ /obj/item/storage/belt/wands/full,
+ /obj/item/voodoo))
+
+// If true, it's the probability of triggering "survivor" antag.
+GLOBAL_VAR_INIT(summon_guns_triggered, FALSE)
+GLOBAL_VAR_INIT(summon_magic_triggered, FALSE)
+
+/proc/give_guns(mob/living/carbon/human/H)
+ if(H.stat == DEAD || !(H.client))
+ return
+ if(H.mind)
+ if(iswizard(H))
+ return
+
+ if(prob(GLOB.summon_guns_triggered) && !(H.mind in SSticker.mode.traitors))
+ SSticker.mode.traitors += H.mind
+
+ H.mind.add_antag_datum(/datum/antagonist/survivalist/guns)
+ H.create_attack_log("was made into a survivalist, and trusts no one!")
+
+ var/gun_type = pick(GLOB.summoned_guns)
+ var/obj/item/gun/G = new gun_type(get_turf(H))
+ playsound(get_turf(H),'sound/magic/summon_guns.ogg', 50, TRUE)
+
+ var/in_hand = H.put_in_hands(G) // not always successful
+
+ to_chat(H, "\A [G] appears [in_hand ? "in your hand" : "at your feet"]!")
+
+/proc/give_magic(mob/living/carbon/human/H)
+ if(H.stat == DEAD || !(H.client))
+ return
+ if(H.mind)
+ if(iswizard(H))
+ return
+
+ if(prob(GLOB.summon_magic_triggered) && !(H.mind in SSticker.mode.traitors))
+ SSticker.mode.traitors += H.mind
+
+ H.mind.add_antag_datum(/datum/antagonist/survivalist/magic)
+ H.create_attack_log("was made into a survivalist, and trusts no one!")
+
+ var/magic_type = pick(GLOB.summoned_magic)
+ var/lucky = FALSE
+ if(prob(SPECIALIST_MAGIC_PROB))
+ magic_type = pick(GLOB.summoned_special_magic)
+ lucky = TRUE
+
+ var/obj/item/M = new magic_type(get_turf(H))
+ playsound(get_turf(H),'sound/magic/summon_magic.ogg', 50, TRUE)
+
+ var/in_hand = H.put_in_hands(M)
+
+ to_chat(H, "\A [M] appears [in_hand ? "in your hand" : "at your feet"]!")
+ if(lucky)
+ to_chat(H, "You feel incredibly lucky.")
+
+/proc/rightandwrong(summon_type, mob/user, survivor_probability)
+ if(user) //in this case either someone holding a spellbook or a badmin
+ to_chat(user, "You summoned [summon_type]!")
+ message_admins("[ADMIN_LOOKUPFLW(user)] summoned [summon_type]!")
+ log_game("[key_name(user)] summoned [summon_type]!")
+
+ if(summon_type == SUMMON_MAGIC)
+ GLOB.summon_magic_triggered = survivor_probability
+ else if(summon_type == SUMMON_GUNS)
+ GLOB.summon_guns_triggered = survivor_probability
+ else
+ CRASH("Bad summon_type given: [summon_type]")
for(var/mob/living/carbon/human/H in GLOB.player_list)
- if(H.stat == 2 || !(H.client))
+ var/turf/T = get_turf(H)
+ if(T && is_away_level(T.z))
continue
- if(H.mind)
- if(H.mind.special_role == SPECIAL_ROLE_WIZARD || H.mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE)
- continue
- var/randomizeguns = pick(gunslist)
- var/randomizemagic = pick(magiclist)
- var/randomizemagicspecial = pick(magicspeciallist)
- if(revolver_fight)
- randomizeguns = "revolver"
- if(fake_revolver_fight)
- if(prob(50))
- randomizeguns = "revolver"
- else
- randomizeguns = "fakerevolver"
- if(!summon_type)
- switch(randomizeguns)
- if("taser")
- new /obj/item/gun/energy/gun/advtaser(get_turf(H))
- if("egun")
- new /obj/item/gun/energy/gun(get_turf(H))
- if("laser")
- new /obj/item/gun/energy/laser(get_turf(H))
- if("revolver")
- new /obj/item/gun/projectile/revolver(get_turf(H))
- if("detective")
- new /obj/item/gun/projectile/revolver/detective(get_turf(H))
- if("deagle")
- new /obj/item/gun/projectile/automatic/pistol/deagle/camo(get_turf(H))
- if("gyrojet")
- new /obj/item/gun/projectile/automatic/gyropistol(get_turf(H))
- if("pulse")
- new /obj/item/gun/energy/pulse(get_turf(H))
- if("suppressed")
- new /obj/item/gun/projectile/automatic/pistol(get_turf(H))
- new /obj/item/suppressor(get_turf(H))
- if("doublebarrel")
- new /obj/item/gun/projectile/revolver/doublebarrel(get_turf(H))
- if("shotgun")
- new /obj/item/gun/projectile/shotgun(get_turf(H))
- if("combatshotgun")
- new /obj/item/gun/projectile/shotgun/automatic/combat(get_turf(H))
- if("arg")
- new /obj/item/gun/projectile/automatic/ar(get_turf(H))
- if("mateba")
- new /obj/item/gun/projectile/revolver/mateba(get_turf(H))
- if("boltaction")
- new /obj/item/gun/projectile/shotgun/boltaction(get_turf(H))
- if("uzi")
- new /obj/item/gun/projectile/automatic/mini_uzi(get_turf(H))
- if("cannon")
- new /obj/item/gun/energy/lasercannon(get_turf(H))
- if("crossbow")
- new /obj/item/gun/energy/kinetic_accelerator/crossbow/large(get_turf(H))
- if("nuclear")
- new /obj/item/gun/energy/gun/nuclear(get_turf(H))
- if("sabr")
- new /obj/item/gun/projectile/automatic/proto(get_turf(H))
- if("bulldog")
- new /obj/item/gun/projectile/automatic/shotgun/bulldog(get_turf(H))
- if("c20r")
- new /obj/item/gun/projectile/automatic/c20r(get_turf(H))
- if("saw")
- new /obj/item/gun/projectile/automatic/l6_saw(get_turf(H))
- if("car")
- new /obj/item/gun/projectile/automatic/m90(get_turf(H))
- if("turret")
- new /obj/item/gun/energy/gun/turret(get_turf(H))
- if("pulsecarbine")
- new /obj/item/gun/energy/pulse/carbine(get_turf(H))
- if("decloner")
- new /obj/item/gun/energy/decloner(get_turf(H))
- if("mindflayer")
- new /obj/item/gun/energy/mindflayer(get_turf(H))
- if("kinetic")
- new /obj/item/gun/energy/kinetic_accelerator(get_turf(H))
- if("advplasmacutter")
- new /obj/item/gun/energy/plasmacutter/adv(get_turf(H))
- if("wormhole")
- new /obj/item/gun/energy/wormhole_projector(get_turf(H))
- if("wt550")
- new /obj/item/gun/projectile/automatic/wt550(get_turf(H))
- if("grenadelauncher")
- new /obj/item/gun/projectile/revolver/grenadelauncher(get_turf(H))
- if("medibeam")
- new /obj/item/gun/medbeam(get_turf(H))
- if("fakerevolver")
- new /obj/item/toy/russian_revolver/trick_revolver(get_turf(H)) //lol
-
- playsound(get_turf(H), 'sound/magic/summon_guns.ogg', 50, 1)
+ if(summon_type == SUMMON_MAGIC)
+ give_magic(H)
else
- switch(randomizemagic)
- if("fireball")
- new /obj/item/spellbook/oneuse/fireball(get_turf(H))
- if("smoke")
- new /obj/item/spellbook/oneuse/smoke(get_turf(H))
- if("blind")
- new /obj/item/spellbook/oneuse/blind(get_turf(H))
- if("mindswap")
- new /obj/item/spellbook/oneuse/mindswap(get_turf(H))
- if("forcewall")
- new /obj/item/spellbook/oneuse/forcewall(get_turf(H))
- if("knock")
- new /obj/item/spellbook/oneuse/knock(get_turf(H))
- if("horsemask")
- new /obj/item/spellbook/oneuse/horsemask(get_turf(H))
- if("charge")
- new /obj/item/spellbook/oneuse/charge(get_turf(H))
- if("summonitem")
- new /obj/item/spellbook/oneuse/summonitem(get_turf(H))
- if("wandnothing")
- new /obj/item/gun/magic/wand(get_turf(H))
- if("wanddeath")
- new /obj/item/gun/magic/wand/death(get_turf(H))
- if("wandresurrection")
- new /obj/item/gun/magic/wand/resurrection(get_turf(H))
- if("wandpolymorph")
- new /obj/item/gun/magic/wand/polymorph(get_turf(H))
- if("wandteleport")
- new /obj/item/gun/magic/wand/teleport(get_turf(H))
- if("wanddoor")
- new /obj/item/gun/magic/wand/door(get_turf(H))
- if("wandfireball")
- new /obj/item/gun/magic/wand/fireball(get_turf(H))
- if("staffhealing")
- new /obj/item/gun/magic/staff/healing(get_turf(H))
- if("staffdoor")
- new /obj/item/gun/magic/staff/door(get_turf(H))
- if("armor")
- new /obj/item/clothing/suit/space/hardsuit/wizard(get_turf(H))
- if("scrying")
- new /obj/item/scrying(get_turf(H))
- if(!(XRAY in H.mutations))
- H.mutations.Add(XRAY)
- H.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
- H.see_in_dark = 8
- H.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
- H.update_sight()
- to_chat(H, "The walls suddenly disappear.")
- if("voodoo")
- new /obj/item/voodoo(get_turf(H))
- if("special")
- magiclist -= "special" //only one super OP item per summoning max
- switch(randomizemagicspecial)
- if("staffchange")
- new /obj/item/gun/magic/staff/change(get_turf(H))
- if("staffanimation")
- new /obj/item/gun/magic/staff/animate(get_turf(H))
- if("wandbelt")
- new /obj/item/storage/belt/wands/full(get_turf(H))
- if("contract")
- new /obj/item/contract(get_turf(H))
- if("staffchaos")
- new /obj/item/gun/magic/staff/chaos(get_turf(H))
- if("necromantic")
- new /obj/item/necromantic_stone(get_turf(H))
- to_chat(H, "You suddenly feel lucky.")
-
- playsound(get_turf(H), 'sound/magic/summon_magic.ogg', 50, 1)
+ give_guns(H)
\ No newline at end of file
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index a71b51c58f0..f67a8f28a5d 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -181,13 +181,13 @@
desc = "A wicked machine used by those skilled in magical arts. It is inactive"
/obj/structure/constructshell/examine(mob/user)
- if(..(user, 0))
- if(iscultist(user) || iswizard(user) || user.stat == DEAD)
- to_chat(user, "A construct shell, used to house bound souls from a soulstone.")
- to_chat(user, "Placing a soulstone with a soul into this shell allows you to produce your choice of the following:")
- to_chat(user, "An Artificer, which can produce more shells and soulstones, as well as fortifications.")
- to_chat(user, "A Wraith, which does high damage and can jaunt through walls, though it is quite fragile.")
- to_chat(user, "A Juggernaut, which is very hard to kill and can produce temporary walls, but is slow.")
+ . = ..()
+ if(in_range(user, src) && (iscultist(user) || iswizard(user) || user.stat == DEAD))
+ . += "A construct shell, used to house bound souls from a soulstone."
+ . += "Placing a soulstone with a soul into this shell allows you to produce your choice of the following:"
+ . += "An Artificer, which can produce more shells and soulstones, as well as fortifications."
+ . += "A Wraith, which does high damage and can jaunt through walls, though it is quite fragile."
+ . += "A Juggernaut, which is very hard to kill and can produce temporary walls, but is slow."
/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob, params)
if(istype(O, /obj/item/soulstone))
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 56cc3594ee2..d2842c21c24 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -295,11 +295,11 @@
/datum/spellbook_entry/summon
name = "Summon Stuff"
category = "Rituals"
- refundable = 0
+ refundable = FALSE
buy_word = "Cast"
- var/active = 0
+ var/active = FALSE
-/datum/spellbook_entry/summon/CanBuy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book)
+/datum/spellbook_entry/summon/CanBuy(mob/living/carbon/human/user, obj/item/spellbook/book)
return ..() && !active
/datum/spellbook_entry/summon/GetInfo()
@@ -337,8 +337,7 @@
/datum/spellbook_entry/summon/guns
name = "Summon Guns"
- desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. Just be careful not to stand still too long! You will also receive 1 extra point to use in your spellbook."
- cost = 0
+ desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. There is a good chance that they will shoot each other first."
log_name = "SG"
/datum/spellbook_entry/summon/guns/IsSpellAvailable()
@@ -349,18 +348,17 @@
else
return TRUE
-/datum/spellbook_entry/summon/guns/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book)
+/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
feedback_add_details("wizard_spell_learned", log_name)
- user.rightandwrong(0)
- book.uses += 1
- active = 1
- to_chat(user, "You have cast summon guns and gained an extra charge for your spellbook.")
- return 1
+ rightandwrong(SUMMON_GUNS, user, 10)
+ active = TRUE
+ playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, TRUE)
+ to_chat(user, "You have cast summon guns!")
+ return TRUE
/datum/spellbook_entry/summon/magic
name = "Summon Magic"
- desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time. You will also receive 1 extra point to use in your spellbook."
- cost = 0
+ desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time."
log_name = "SU"
/datum/spellbook_entry/summon/magic/IsSpellAvailable()
@@ -371,13 +369,13 @@
else
return TRUE
-/datum/spellbook_entry/summon/magic/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book)
+/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
feedback_add_details("wizard_spell_learned", log_name)
- user.rightandwrong(1)
- book.uses += 1
- active = 1
- to_chat(user, "You have cast summon magic and gained an extra charge for your spellbook.")
- return 1
+ rightandwrong(SUMMON_MAGIC, user, 10)
+ active = TRUE
+ playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, TRUE)
+ to_chat(user, "You have cast summon magic!")
+ return TRUE
//Main category - Magical Items
/datum/spellbook_entry/item
@@ -446,18 +444,21 @@
category = "Artefacts"
//Weapons and Armors
-/datum/spellbook_entry/item/armor
- name = "Mastercrafted Armor Set"
- desc = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space. Comes bundled with Boots of Gripping."
- item_path = /obj/item/clothing/suit/space/hardsuit/wizard
- log_name = "HS"
+/datum/spellbook_entry/item/battlemage
+ name = "Battlemage Armour"
+ desc = "An ensorceled suit of armour, protected by a powerful shield. The shield can completely negate sixteen attacks before being permanently depleted."
+ item_path = /obj/item/clothing/suit/space/hardsuit/shielded/wizard
+ limit = 1
category = "Weapons and Armors"
+ log_name = "BMA"
-/datum/spellbook_entry/item/armor/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book)
- . = ..()
- if(.)
- new /obj/item/clothing/shoes/sandal(get_turf(user)) //In case they've lost them.
- new /obj/item/clothing/gloves/color/purple(get_turf(user)) // To complete the outfit
+/datum/spellbook_entry/item/battlemage_charge
+ name = "Battlemage Armour Charges"
+ desc = "A powerful defensive rune, it will grant eight additional charges to a suit of battlemage armour."
+ item_path = /obj/item/wizard_armour_charge
+ category = "Weapons and Armors"
+ cost = 1
+ log_name = "BMAC"
/datum/spellbook_entry/item/mjolnir
name = "Mjolnir"
@@ -863,10 +864,7 @@
/obj/item/spellbook/oneuse/smoke/recoil(mob/user as mob)
..()
to_chat(user, "Your stomach rumbles...")
- if(user.nutrition)
- user.nutrition -= 200
- if(user.nutrition <= 0)
- user.nutrition = 0
+ user.adjust_nutrition(-200)
/obj/item/spellbook/oneuse/blind
spell = /obj/effect/proc_holder/spell/targeted/trigger/blind
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index b2ab6daa934..6a1af5693c9 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -319,10 +319,9 @@
if(occupant)
to_chat(user, "The sleeper is already occupied!")
return
- for(var/mob/living/carbon/slime/M in range(1, G.affecting))
- if(M.Victim == G.affecting)
- to_chat(user, "[G.affecting.name] will not fit into the sleeper because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.")
- return
+ if(G.affecting.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[G.affecting] will not fit into [src] because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.")
+ return
visible_message("[user] starts putting [G.affecting.name] into the sleeper.")
@@ -479,10 +478,9 @@
if(L.abiotic())
to_chat(user, "Subject cannot have abiotic items on.")
return
- for(var/mob/living/carbon/slime/M in range(1,L))
- if(M.Victim == L)
- to_chat(usr, "[L.name] will not fit into the sleeper because [L.p_they()] [L.p_have()] a slime latched onto their head.")
- return
+ if(L.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")
+ return
if(L == user)
visible_message("[user] starts climbing into the sleeper.")
else
@@ -520,10 +518,9 @@
return
if(usr.incapacitated()) //are you cuffed, dying, lying, stunned or other
return
- for(var/mob/living/carbon/slime/M in range(1,usr))
- if(M.Victim == usr)
- to_chat(usr, "You're too busy getting your life sucked out of you.")
- return
+ if(usr.has_buckled_mobs()) //mob attached to us
+ to_chat(usr, "[usr] will not fit into [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head.")
+ return
visible_message("[usr] starts climbing into the sleeper.")
if(do_after(usr, 20, target = usr))
if(occupant)
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index e1d15657bdc..d7f85b2045f 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -77,10 +77,9 @@
if(occupant)
to_chat(user, "The scanner is already occupied!")
return
- for(var/mob/living/carbon/slime/M in range(1, TYPECAST_YOUR_SHIT.affecting))
- if(M.Victim == TYPECAST_YOUR_SHIT.affecting)
- to_chat(user, "[TYPECAST_YOUR_SHIT.affecting.name] has a fucking slime attached to [TYPECAST_YOUR_SHIT.affecting.p_them()], deal with that first.")
- return
+ if(TYPECAST_YOUR_SHIT.affecting.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[TYPECAST_YOUR_SHIT.affecting] will not fit into [src] because [TYPECAST_YOUR_SHIT.affecting.p_they()] [TYPECAST_YOUR_SHIT.affecting.p_have()] a fucking slime latched onto [TYPECAST_YOUR_SHIT.affecting.p_their()] head.")
+ return
var/mob/living/carbon/human/M = TYPECAST_YOUR_SHIT.affecting
if(M.abiotic())
to_chat(user, "Subject cannot have abiotic items on.")
@@ -117,10 +116,9 @@
if(H.abiotic())
to_chat(user, "Subject cannot have abiotic items on.")
return FALSE
- for(var/mob/living/carbon/slime/M in range(1, H))
- if(M.Victim == H)
- to_chat(user, "[H] has a fucking slime attached to [H.p_them()], deal with that first.")
- return FALSE
+ if(H.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[H] will not fit into [src] because [H.p_they()] [H.p_have()] a slime latched onto [H.p_their()] head.")
+ return
if(H == user)
visible_message("[user] climbs into [src].")
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 9cbb17cd12b..ea5eb96cce9 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -1034,11 +1034,11 @@
update_icon()
/obj/machinery/alarm/examine(mob/user)
- ..(user)
+ . = ..()
if(buildstage < 2)
- to_chat(user, "It is not wired.")
+ . += "It is not wired."
if(buildstage < 1)
- to_chat(user, "The circuit is missing.")
+ . += "The circuit is missing."
/obj/machinery/alarm/all_access
name = "all-access air alarm"
diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm
index c02743ceaac..5b68ef2aff0 100644
--- a/code/game/machinery/atmoalter/meter.dm
+++ b/code/game/machinery/atmoalter/meter.dm
@@ -113,7 +113,7 @@
else
t += "The connect error light is blinking."
- to_chat(user, t)
+ . = list(t)
/obj/machinery/meter/Click()
if(istype(usr, /mob/living/silicon/ai)) // ghosts can call ..() for examine
diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm
index d443aee53e2..f5bdfbacaa0 100644
--- a/code/game/machinery/atmoalter/portable_atmospherics.dm
+++ b/code/game/machinery/atmoalter/portable_atmospherics.dm
@@ -95,9 +95,9 @@
replace_tank(user, TRUE)
/obj/machinery/portable_atmospherics/examine(mob/user)
- ..()
+ . = ..()
if(holding)
- to_chat(user, "\The [src] contains [holding]. Alt-click [src] to remove it.")
+ . += "\The [src] contains [holding]. Alt-click [src] to remove it."
/obj/machinery/portable_atmospherics/proc/replace_tank(mob/living/user, close_valve, obj/item/tank/new_tank)
if(holding)
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index 0d4455399b0..813120b7c42 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -32,10 +32,10 @@
overlays.Cut()
/obj/machinery/cell_charger/examine(mob/user)
- ..()
- to_chat(user, "There's [charging ? "a" : "no"] cell in the charger.")
+ . = ..()
+ . += "There's [charging ? "a" : "no"] cell in the charger."
if(charging)
- to_chat(user, "Current charge: [round(charging.percent(), 1)]%")
+ . += "Current charge: [round(charging.percent(), 1)]%"
/obj/machinery/cell_charger/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/stock_parts/cell))
diff --git a/code/game/machinery/chiller.dm b/code/game/machinery/chiller.dm
index d2f76a7c42a..afb17f3c90a 100644
--- a/code/game/machinery/chiller.dm
+++ b/code/game/machinery/chiller.dm
@@ -25,12 +25,12 @@
return
/obj/machinery/space_heater/air_conditioner/examine(mob/user)
- ..(user)
- to_chat(user, "The air conditioner is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"].")
+ . = ..()
+ . += "The air conditioner is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"]."
if(open)
- to_chat(user, "The power cell is [cell ? "installed" : "missing"].")
+ . += "The power cell is [cell ? "installed" : "missing"]."
else
- to_chat(user, "The charge meter reads [cell ? round(cell.percent(),1) : 0]%")
+ . += "The charge meter reads [cell ? round(cell.percent(),1) : 0]%"
/obj/machinery/space_heater/air_conditioner/emp_act(severity)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 1ce0bcd97e7..26e6b8f4d7f 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -164,19 +164,19 @@
to_chat(user, "You flip the write-protect tab to [read_only ? "protected" : "unprotected"].")
/obj/item/disk/data/examine(mob/user)
- ..(user)
- to_chat(user, "The write-protect tab is set to [read_only ? "protected" : "unprotected"].")
+ . = ..()
+ . += "The write-protect tab is set to [read_only ? "protected" : "unprotected"]."
//Clonepod
/obj/machinery/clonepod/examine(mob/user)
- ..()
+ . = ..()
if(mess)
- to_chat(user, "It's filled with blood and viscera. You swear you can see it moving...")
+ . += "It's filled with blood and viscera. You swear you can see it moving..."
if(!occupant || stat & (NOPOWER|BROKEN))
return
if(occupant && occupant.stat != DEAD)
- to_chat(user, "Current clone cycle is [round(get_completion())]% complete.")
+ . += "Current clone cycle is [round(get_completion())]% complete."
/obj/machinery/clonepod/return_air() //non-reactive air
var/datum/gas_mixture/GM = new
@@ -430,8 +430,6 @@
SSticker.mode.add_cultist(occupant.mind)
SSticker.mode.update_cult_icons_added() //So the icon actually appears
SSticker.mode.update_cult_comms_added(H.mind) //So the comms actually appears
- if((H.mind in SSticker.mode.implanter) || (H.mind in SSticker.mode.implanted))
- SSticker.mode.update_traitor_icons_added(H.mind) //So the icon actually appears
if(H.mind.vampire)
H.mind.vampire.update_owner(H)
if((H.mind in SSticker.mode.vampire_thralls) || (H.mind in SSticker.mode.vampire_enthralled))
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index c9d7f10302a..a56d5c40236 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -367,7 +367,7 @@
if(food <= 0)
dat += "
You ran out of food and starved."
if(emagged)
- user.nutrition = 0 //yeah you pretty hongry
+ user.set_nutrition(0) //yeah you pretty hongry
to_chat(user, "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor.")
if(fuel <= 0)
dat += "
You ran out of fuel, and drift, slowly, into a star."
@@ -467,7 +467,7 @@
sleep(30)
atom_say("[M] violently throws up!")
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
- M.nutrition -= 50 //lose a lot of food
+ M.adjust_nutrition(-50) //lose a lot of food
var/turf/location = usr.loc
if(istype(location, /turf/simulated))
location.add_vomit_floor(TRUE)
@@ -980,13 +980,12 @@
var/active = 0 //if the ship is on
/obj/item/orion_ship/examine(mob/user)
- ..()
- if(!(in_range(user, src)))
- return
- if(!active)
- to_chat(user, "There's a little switch on the bottom. It's flipped down.")
- else
- to_chat(user, "There's a little switch on the bottom. It's flipped up.")
+ . = ..()
+ if(in_range(user, src))
+ if(!active)
+ . += "There's a little switch on the bottom. It's flipped down."
+ else
+ . += "There's a little switch on the bottom. It's flipped up."
/obj/item/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse
if(active)
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index a34a49ca051..c0384e63b94 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -57,7 +57,7 @@
board_type = "machine"
/obj/item/circuitboard/examine(mob/user)
- ..()
+ . = ..()
if(LAZYLEN(req_components))
var/list/nice_list = list()
for(var/B in req_components)
@@ -65,7 +65,7 @@
if(!ispath(A))
continue
nice_list += list("[req_components[A]] [initial(A.name)]")
- to_chat(user,"Required components: [english_list(nice_list)].")
+ . += "Required components: [english_list(nice_list)]."
/obj/item/circuitboard/message_monitor
name = "Circuit board (Message Monitor)"
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index 21452131e76..e1f595f4dfd 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -382,6 +382,8 @@ to destroy them and players will be able to make replacements.
/obj/item/stock_parts/console_screen = 1,
/obj/item/stock_parts/scanning_module = 1)
+/obj/item/circuitboard/plantgenes/vault
+
/obj/item/circuitboard/seed_extractor
name = "circuit board (Seed Extractor)"
build_path = /obj/machinery/seed_extractor
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index 680f261c30f..6c8c26785ce 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -108,10 +108,9 @@
if(L.abiotic())
to_chat(user, "Subject cannot have abiotic items on.")
return
- for(var/mob/living/carbon/slime/M in range(1,L))
- if(M.Victim == L)
- to_chat(usr, "[L.name] will not fit into the cryo cell because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")
- return
+ if(L.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")
+ return
if(put_mob(L))
if(L == user)
visible_message("[user] climbs into the cryo cell.")
@@ -305,10 +304,9 @@
return
if(!ismob(GG.affecting))
return
- for(var/mob/living/carbon/slime/M in range(1,GG.affecting))
- if(M.Victim == GG.affecting)
- to_chat(usr, "[GG.affecting.name] will not fit into the cryo because [GG.affecting.p_they()] [GG.affecting.p_have()] a slime latched onto [GG.affecting.p_their()] head.")
- return
+ if(GG.affecting.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[GG.affecting] will not fit into [src] because [GG.affecting.p_they()] [GG.affecting.p_have()] a slime latched onto [GG.affecting.p_their()] head.")
+ return
var/mob/M = GG.affecting
if(put_mob(M))
qdel(GG)
@@ -468,10 +466,9 @@
set category = "Object"
set src in oview(1)
- for(var/mob/living/carbon/slime/M in range(1,usr))
- if(M.Victim == usr)
- to_chat(usr, "You're too busy getting your life sucked out of you.")
- return
+ if(usr.has_buckled_mobs()) //mob attached to us
+ to_chat(usr, "[usr] will not fit into [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head.")
+ return
if(stat & (NOPOWER|BROKEN))
return
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index f9d708a6200..9d6be29c84f 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -554,10 +554,9 @@
to_chat(user, "Dead people can not be put into cryo.")
return
- for(var/mob/living/carbon/slime/M in range(1,L))
- if(M.Victim == L)
- to_chat(usr, "[L.name] will not fit into the cryo pod because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")
- return
+ if(L.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.")
+ return
var/willing = null //We don't want to allow people to be forced into despawning.
@@ -658,10 +657,9 @@
to_chat(usr, "\The [src] is in use.")
return
- for(var/mob/living/carbon/slime/M in range(1,usr))
- if(M.Victim == usr)
- to_chat(usr, "You're too busy getting your life sucked out of you.")
- return
+ if(usr.has_buckled_mobs()) //mob attached to us
+ to_chat(usr, "[usr] will not fit into [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head.")
+ return
visible_message("[usr] starts climbing into [src].")
diff --git a/code/game/machinery/defib_mount.dm b/code/game/machinery/defib_mount.dm
index 77d68590efa..4f27dfa4be5 100644
--- a/code/game/machinery/defib_mount.dm
+++ b/code/game/machinery/defib_mount.dm
@@ -42,15 +42,15 @@
return ..()
/obj/machinery/defibrillator_mount/examine(mob/user)
- ..()
+ . = ..()
if(defib)
- to_chat(user, "There is a defib unit hooked up. Alt-click to remove it.")
+ . += "There is a defib unit hooked up. Alt-click to remove it."
if(security_level >= SEC_LEVEL_RED)
- to_chat(user, "Due to a security situation, its locking clamps can be toggled by swiping any ID.")
+ . += "Due to a security situation, its locking clamps can be toggled by swiping any ID."
else
- to_chat(user, "Its locking clamps can be [clamps_locked ? "dis" : ""]engaged by swiping an ID with access.")
+ . += "Its locking clamps can be [clamps_locked ? "dis" : ""]engaged by swiping an ID with access."
else
- to_chat(user, "There are a pair of bolts in the defib unit housing securing the [src] to the wall.")
+ . += "There are a pair of bolts in the defib unit housing securing the [src] to the wall."
/obj/machinery/defibrillator_mount/process()
if(defib && defib.bcell && defib.bcell.charge < defib.bcell.maxcharge && is_operational())
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index 310111f6887..7333ddca611 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -146,7 +146,7 @@
/obj/item/grenade/barrier/examine(mob/user)
. = ..()
- to_chat(user, "Alt-click to toggle modes.")
+ . += "Alt-click to toggle modes."
/obj/item/grenade/barrier/AltClick(mob/living/carbon/user)
if(!istype(user) || !user.Adjacent(src) || user.incapacitated())
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index ceda2ab97a2..a36dbe7a9a6 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -501,38 +501,38 @@ About the new airlock wires panel:
update_icon(AIRLOCK_CLOSED)
/obj/machinery/door/airlock/examine(mob/user)
- ..()
+ . = ..()
if(emagged)
- to_chat(user, "Its access panel is smoking slightly.")
+ . += "Its access panel is smoking slightly."
if(note)
if(!in_range(user, src))
- to_chat(user, "There's a [note.name] pinned to the front. You can't [note_type() == "note" ? "read" : "see"] it from here.")
+ . += "There's a [note.name] pinned to the front. You can't [note_type() == "note" ? "read" : "see"] it from here."
else
- to_chat(user, "There's a [note.name] pinned to the front...")
+ . += "There's a [note.name] pinned to the front..."
note.examine(user)
- to_chat(user, "Use an empty hand on the airlock on grab mode to remove [note.name].")
+ . += "Use an empty hand on the airlock on grab mode to remove [note.name]."
if(panel_open)
switch(security_level)
if(AIRLOCK_SECURITY_NONE)
- to_chat(user, "Its wires are exposed!")
+ . += "Its wires are exposed!"
if(AIRLOCK_SECURITY_METAL)
- to_chat(user, "Its wires are hidden behind a welded metal cover.")
+ . += "Its wires are hidden behind a welded metal cover."
if(AIRLOCK_SECURITY_PLASTEEL_I_S)
- to_chat(user, "There is some shredded plasteel inside.")
+ . += "There is some shredded plasteel inside."
if(AIRLOCK_SECURITY_PLASTEEL_I)
- to_chat(user, "Its wires are behind an inner layer of plasteel.")
+ . += "Its wires are behind an inner layer of plasteel."
if(AIRLOCK_SECURITY_PLASTEEL_O_S)
- to_chat(user, "There is some shredded plasteel inside.")
+ . += "There is some shredded plasteel inside."
if(AIRLOCK_SECURITY_PLASTEEL_O)
- to_chat(user, "There is a welded plasteel cover hiding its wires.")
+ . += "There is a welded plasteel cover hiding its wires."
if(AIRLOCK_SECURITY_PLASTEEL)
- to_chat(user, "There is a protective grille over its panel.")
+ . += "There is a protective grille over its panel."
else if(security_level)
if(security_level == AIRLOCK_SECURITY_METAL)
- to_chat(user, "It looks a bit stronger.")
+ . += "It looks a bit stronger."
else
- to_chat(user, "It looks very robust.")
+ . += "It looks very robust."
/obj/machinery/door/airlock/attack_ghost(mob/user)
if(panel_open)
@@ -1196,8 +1196,8 @@ About the new airlock wires panel:
return 1
/obj/machinery/door/airlock/CanAStarPass(obj/item/card/id/ID)
-//Airlock is passable if it is open (!density), bot has access, and is not bolted shut)
- return !density || (check_access(ID) && !locked && arePowerSystemsOn())
+//Airlock is passable if it is open (!density), bot has access, and is not bolted or welded shut)
+ return !density || (check_access(ID) && !locked && !welded && arePowerSystemsOn())
/obj/machinery/door/airlock/emag_act(mob/user)
if(!operating && density && arePowerSystemsOn() && !emagged)
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index d874367e261..689b602af3f 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -33,15 +33,15 @@
var/active_alarm = FALSE
/obj/machinery/door/firedoor/examine(mob/user)
- ..()
+ . = ..()
if(!density)
- to_chat(user, "It is open, but could be pried closed.")
+ . += "It is open, but could be pried closed."
else if(!welded)
- to_chat(user, "It is closed, but could be pried open. Deconstruction would require it to be welded shut.")
+ . += "It is closed, but could be pried open. Deconstruction would require it to be welded shut."
else if(boltslocked)
- to_chat(user, "It is welded shut. The floor bolts have been locked by screws.")
+ . += "It is welded shut. The floor bolts have been locked by screws."
else
- to_chat(user, "The bolt locks have been unscrewed, but the bolts themselves are still wrenched to the floor.")
+ . += "The bolt locks have been unscrewed, but the bolts themselves are still wrenched to the floor."
/obj/machinery/door/firedoor/closed
icon_state = "door_closed"
@@ -289,18 +289,18 @@
var/reinforced = 0
/obj/structure/firelock_frame/examine(mob/user)
- ..()
+ . = ..()
switch(constructionStep)
if(CONSTRUCTION_PANEL_OPEN)
- to_chat(user, "It is unbolted from the floor. A small loosely connected metal plate is covering the wires.")
+ . += "It is unbolted from the floor. A small loosely connected metal plate is covering the wires."
if(!reinforced)
- to_chat(user, "It could be reinforced with plasteel.")
+ . += "It could be reinforced with plasteel."
if(CONSTRUCTION_WIRES_EXPOSED)
- to_chat(user, "The maintenance plate has been pried away, and wires are trailing.")
+ . += "The maintenance plate has been pried away, and wires are trailing."
if(CONSTRUCTION_GUTTED)
- to_chat(user, "The maintenance panel is missing wires and the circuit board is loosely connected.")
+ . += "The maintenance panel is missing wires and the circuit board is loosely connected."
if(CONSTRUCTION_NOCIRCUIT)
- to_chat(user, "There are no firelock electronics in the frame. The frame could be cut apart.")
+ . += "There are no firelock electronics in the frame. The frame could be cut apart."
/obj/structure/firelock_frame/update_icon()
..()
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index fab127be057..1da2db42ffc 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -54,9 +54,9 @@
icon_state = "[base_state]open"
/obj/machinery/door/window/examine(mob/user)
- ..()
+ . = ..()
if(emagged)
- to_chat(user, "Its access panel is smoking slightly.")
+ . += "Its access panel is smoking slightly."
/obj/machinery/door/window/proc/open_and_close()
open()
diff --git a/code/game/machinery/guestpass.dm b/code/game/machinery/guestpass.dm
index 450260f5f79..4bc080fca67 100644
--- a/code/game/machinery/guestpass.dm
+++ b/code/game/machinery/guestpass.dm
@@ -17,15 +17,15 @@
return temp_access
/obj/item/card/id/guest/examine(mob/user)
- ..(user)
+ . = ..()
if(world.time < expiration_time)
- to_chat(user, "This pass expires at [station_time_timestamp("hh:mm:ss", expiration_time)].")
+ . += "This pass expires at [station_time_timestamp("hh:mm:ss", expiration_time)]."
else
- to_chat(user, "It expired at [station_time_timestamp("hh:mm:ss", expiration_time)].")
- to_chat(user, "It grants access to following areas:")
+ . += "It expired at [station_time_timestamp("hh:mm:ss", expiration_time)]."
+ . += "It grants access to following areas:"
for(var/A in temp_access)
- to_chat(user, "[get_access_desc(A)].")
- to_chat(user, "Issuing reason: [reason].")
+ . += "[get_access_desc(A)]."
+ . += "Issuing reason: [reason]."
/////////////////////////////////////////////
//Guest pass terminal////////////////////////
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 3c7f3ab3cd0..b9e8626ae95 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -479,8 +479,9 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/effect/overlay/holo_pad_hologram/examine(mob/user)
if(Impersonation)
- return Impersonation.examine(user)
- return ..()
+ . = Impersonation.examine(user)
+ else
+ . = ..()
/obj/effect/overlay/holoray
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index f3be556a184..144b441d2de 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -56,9 +56,9 @@
return ..()
/obj/machinery/iv_drip/examine(mob/user)
- ..(user)
+ . = ..()
if(bag)
- bag.examine(user)
+ . += bag.examine(user)
/obj/machinery/iv_drip/Move(NewLoc, direct)
. = ..()
diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm
index ee6bd060c16..b1e335c1ce9 100644
--- a/code/game/machinery/lightswitch.dm
+++ b/code/game/machinery/lightswitch.dm
@@ -70,8 +70,8 @@
icon_state = "light0"
/obj/machinery/light_switch/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "A light switch. It is [on? "on" : "off"].")
+ . = ..()
+ . += "A light switch. It is [on? "on" : "off"]."
/obj/machinery/light_switch/attack_ghost(mob/user)
if(user.can_advanced_admin_interact())
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index f58163d2e71..4f0ef707049 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -484,27 +484,27 @@ Class Procs:
return 0
/obj/machinery/proc/display_parts(mob/user)
- to_chat(user, "Following parts detected in the machine:")
+ . = list("Following parts detected in the machine:")
for(var/obj/item/C in component_parts)
- to_chat(user, "[bicon(C)] [C.name]")
+ . += "[bicon(C)] [C.name]"
/obj/machinery/examine(mob/user)
- ..()
+ . = ..()
if(stat & BROKEN)
- to_chat(user, "It looks broken and non-functional.")
+ . += "It looks broken and non-functional."
if(!(resistance_flags & INDESTRUCTIBLE))
if(resistance_flags & ON_FIRE)
- to_chat(user, "It's on fire!")
+ . += "It's on fire!"
var/healthpercent = (obj_integrity/max_integrity) * 100
switch(healthpercent)
if(50 to 99)
- to_chat(user, "It looks slightly damaged.")
+ . += "It looks slightly damaged."
if(25 to 50)
- to_chat(user, "It appears heavily damaged.")
+ . += "It appears heavily damaged."
if(0 to 25)
- to_chat(user, "It's falling apart!")
+ . += "It's falling apart!"
if(user.research_scanner && component_parts)
- display_parts(user)
+ . += display_parts(user)
/obj/machinery/proc/on_assess_perp(mob/living/carbon/human/perp)
return 0
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 5abfc313047..ff5410f6953 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -177,21 +177,21 @@
icon_state = icon_state_idle
/obj/machinery/recharger/examine(mob/user)
- ..()
+ . = ..()
if(charging && (!in_range(user, src) && !issilicon(user) && !isobserver(user)))
- to_chat(user, "You're too far away to examine [src]'s contents and display!")
+ . += "You're too far away to examine [src]'s contents and display!"
return
if(charging)
- to_chat(user, "\The [src] contains:")
- to_chat(user, "- \A [charging].")
+ . += "\The [src] contains:"
+ . += "- \A [charging]."
if(!(stat & (NOPOWER|BROKEN)))
var/obj/item/stock_parts/cell/C = charging.get_cell()
- to_chat(user, "The status display reads:")
+ . += "The status display reads:"
if(using_power)
- to_chat(user, "- Recharging [(C.chargerate/C.maxcharge)*100]% cell charge per cycle.")
+ . += "- Recharging [(C.chargerate/C.maxcharge)*100]% cell charge per cycle."
if(charging)
- to_chat(user, "- \The [charging]'s cell is at [C.percent()]%.")
+ . += "- \The [charging]'s cell is at [C.percent()]%."
// Atlantis: No need for that copy-pasta code, just use var to store icon_states instead.
/obj/machinery/recharger/wallcharger
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 42f80b50004..db89b84cf1e 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -147,7 +147,7 @@
else if(istype(occupant, /mob/living/carbon/human))
var/mob/living/carbon/human/H = occupant
if(H.get_int_organ(/obj/item/organ/internal/cell) && H.nutrition < 450)
- H.nutrition = min(H.nutrition+recharge_speed_nutrition, 450)
+ H.set_nutrition(min(H.nutrition + recharge_speed_nutrition, 450))
if(repairs)
H.heal_overall_damage(repairs, repairs, TRUE, 0, 1)
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index 99d3b135a08..eb3052dd909 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -41,10 +41,10 @@ var/const/SAFETY_COOLDOWN = 100
amount_produced = min(100, amt_made)
/obj/machinery/recycler/examine(mob/user)
- ..(user)
- to_chat(user, "The power light is [(stat & NOPOWER) ? "off" : "on"].")
- to_chat(user, "The safety-mode light is [safety_mode ? "on" : "off"].")
- to_chat(user, "The safety-sensors status light is [emagged ? "off" : "on"].")
+ . = ..()
+ . += "The power light is [(stat & NOPOWER) ? "off" : "on"]."
+ . += "The safety-mode light is [safety_mode ? "on" : "off"]."
+ . += "The safety-sensors status light is [emagged ? "off" : "on"]."
/obj/machinery/recycler/power_change()
..()
diff --git a/code/game/machinery/snow_machine.dm b/code/game/machinery/snow_machine.dm
index 2ae3bf22977..cc59f0a3017 100644
--- a/code/game/machinery/snow_machine.dm
+++ b/code/game/machinery/snow_machine.dm
@@ -25,8 +25,8 @@
RefreshParts()
/obj/machinery/snow_machine/examine(mob/user)
- ..()
- to_chat(user, "The internal reservoir indicates it is [infinite_snow ? "100" : round(reagents.total_volume / reagents.maximum_volume * 100)]% full.")
+ . = ..()
+ . += "The internal reservoir indicates it is [infinite_snow ? "100" : round(reagents.total_volume / reagents.maximum_volume * 100)]% full."
/obj/machinery/snow_machine/RefreshParts()
power_efficiency = 0
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index 86f075bbcd6..fd034999a76 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -35,12 +35,12 @@
return
/obj/machinery/space_heater/examine(mob/user)
- ..(user)
- to_chat(user, "The heater is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"].")
+ . = ..()
+ . += "The heater is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"]."
if(open)
- to_chat(user, "The power cell is [cell ? "installed" : "missing"].")
+ . += "The power cell is [cell ? "installed" : "missing"]."
else
- to_chat(user, "The charge meter reads [cell ? round(cell.percent(),1) : 0]%")
+ . += "The charge meter reads [cell ? round(cell.percent(),1) : 0]%"
/obj/machinery/space_heater/emp_act(severity)
if(stat & (BROKEN|NOPOWER))
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index 642676c6eff..94d1162349f 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -136,9 +136,9 @@
return 0
/obj/machinery/status_display/examine(mob/user)
- . = ..(user)
+ . = ..()
if(mode != STATUS_DISPLAY_BLANK && mode != STATUS_DISPLAY_ALERT)
- to_chat(user, "The display says:
\t[sanitize(message1)]
\t[sanitize(message2)]")
+ . += "The display says:
\t[sanitize(message1)]
\t[sanitize(message2)]"
/obj/machinery/status_display/proc/set_message(m1, m2)
if(m1)
diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm
index 1a63371915b..ed12291c79b 100644
--- a/code/game/machinery/syndicatebeacon.dm
+++ b/code/game/machinery/syndicatebeacon.dm
@@ -57,9 +57,6 @@
return
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/N = M
- SSticker.mode.equip_traitor(N)
- SSticker.mode.traitors += N.mind
- N.mind.special_role = SPECIAL_ROLE_TRAITOR
var/objective = "Free Objective"
switch(rand(1,100))
if(1 to 50)
@@ -74,23 +71,17 @@
objective = "Kill all monkeys aboard the station."
else
objective = "Make certain at least 80% of the station evacuates on the shuttle."
+
var/datum/objective/custom_objective = new(objective)
- custom_objective.owner = N.mind
- N.mind.objectives += custom_objective
-
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = N.mind
- N.mind.objectives += escape_objective
-
-
+ var/datum/antagonist/traitor/T = new()
+ T.give_objectives = FALSE
+ T.add_objective(custom_objective)
+ T.add_objective(/datum/objective/escape)
+ N.mind.add_antag_datum(T)
+
to_chat(M, "You have joined the ranks of the Syndicate and become a traitor to the station!")
-
message_admins("[key_name_admin(N)] has accepted a traitor objective from a syndicate beacon.")
- var/obj_count = 1
- for(var/datum/objective/OBJ in M.mind.objectives)
- to_chat(M, "Objective #[obj_count]: [OBJ.explanation_text]")
- obj_count++
src.add_fingerprint(usr)
src.updateUsrDialog()
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 3fdedd4224e..451351be224 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -90,8 +90,8 @@
return ..()
/obj/machinery/syndicatebomb/examine(mob/user)
- ..(user)
- to_chat(user, "A digital display on it reads \"[seconds_remaining()]\".")
+ . = ..()
+ . += "A digital display on it reads \"[seconds_remaining()]\"."
/obj/machinery/syndicatebomb/update_icon()
icon_state = "[initial(icon_state)][active ? "-active" : "-inactive"][open_panel ? "-wires" : ""]"
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index d61785381ed..13837e2581f 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -1270,7 +1270,6 @@
products = list(/obj/item/seeds/aloe =3,
/obj/item/seeds/ambrosia = 3,
/obj/item/seeds/apple = 3,
- /obj/item/seeds/cotton = 3,
/obj/item/seeds/banana = 3,
/obj/item/seeds/berry = 3,
/obj/item/seeds/cabbage = 3,
@@ -1282,6 +1281,7 @@
/obj/item/seeds/coffee = 3,
/obj/item/seeds/comfrey =3,
/obj/item/seeds/corn = 3,
+ /obj/item/seeds/cotton = 3,
/obj/item/seeds/nymph =3,
/obj/item/seeds/eggplant = 3,
/obj/item/seeds/garlic = 3,
@@ -1293,14 +1293,14 @@
/obj/item/seeds/orange = 3,
/obj/item/seeds/peanuts = 3,
/obj/item/seeds/pineapple = 3,
- /obj/item/seeds/potato = 3,
/obj/item/seeds/poppy = 3,
+ /obj/item/seeds/potato = 3,
/obj/item/seeds/pumpkin = 3,
/obj/item/seeds/replicapod = 3,
/obj/item/seeds/wheat/rice = 3,
/obj/item/seeds/soya = 3,
- /obj/item/seeds/sunflower = 3,
/obj/item/seeds/sugarcane = 3,
+ /obj/item/seeds/sunflower = 3,
/obj/item/seeds/tea = 3,
/obj/item/seeds/tobacco = 3,
/obj/item/seeds/tomato = 3,
@@ -1308,15 +1308,15 @@
/obj/item/seeds/watermelon = 3,
/obj/item/seeds/wheat = 3,
/obj/item/seeds/whitebeet = 3)
- contraband = list(/obj/item/seeds/amanita = 2,
+ contraband = list(/obj/item/seeds/cannabis = 3,
+ /obj/item/seeds/amanita = 2,
+ /obj/item/seeds/fungus = 3,
/obj/item/seeds/glowshroom = 2,
/obj/item/seeds/liberty = 2,
/obj/item/seeds/nettle = 2,
/obj/item/seeds/plump = 2,
/obj/item/seeds/reishi = 2,
- /obj/item/seeds/cannabis = 3,
/obj/item/seeds/starthistle = 2,
- /obj/item/seeds/fungus = 3,
/obj/item/seeds/random = 2)
premium = list(/obj/item/reagent_containers/spray/waterflower = 1)
refill_canister = /obj/item/vending_refill/hydroseeds
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index d1f253d007a..30dcd868a88 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -146,9 +146,7 @@
C.forceMove(src)
cell = C
return
- cell = new(src)
- cell.charge = 15000
- cell.maxcharge = 15000
+ cell = new/obj/item/stock_parts/cell/high/plus(src)
/obj/mecha/proc/add_cabin()
cabin_air = new
@@ -166,23 +164,23 @@
radio.subspace_transmission = 1
/obj/mecha/examine(mob/user)
- ..(user)
+ . = ..()
var/integrity = health/initial(health)*100
switch(integrity)
if(85 to 100)
- to_chat(user, "It's fully intact.")
+ . += "It's fully intact."
if(65 to 85)
- to_chat(user, "It's slightly damaged.")
+ . += "It's slightly damaged."
if(45 to 65)
- to_chat(user, "It's badly damaged.")
+ . += "It's badly damaged."
if(25 to 45)
- to_chat(user, "It's heavily damaged.")
+ . += "It's heavily damaged."
else
- to_chat(user, "It's falling apart.")
+ . += "It's falling apart."
if(equipment && equipment.len)
- to_chat(user, "It's equipped with:")
+ . += "It's equipped with:"
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
- to_chat(user, "[bicon(ME)] [ME]")
+ . += "[bicon(ME)] [ME]"
/obj/mecha/hear_talk(mob/M, list/message_pieces)
if(M == occupant && radio.broadcasting)
@@ -1107,10 +1105,6 @@
if(user.has_buckled_mobs()) //mob attached to us
to_chat(user, "You can't enter the exosuit with other creatures attached to you!")
return
- for(var/mob/living/carbon/slime/S in range(1,user))
- if(S.Victim == user)
- to_chat(user, "You're too busy getting your life sucked out of you.")
- return
visible_message("[user] starts to climb into [src]")
diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm
index c5e3417d89d..3308acffcd8 100644
--- a/code/game/objects/effects/decals/Cleanable/humans.dm
+++ b/code/game/objects/effects/decals/Cleanable/humans.dm
@@ -142,8 +142,8 @@ var/global/list/image/splatter_cache = list()
icon_state = "writing1"
/obj/effect/decal/cleanable/blood/writing/examine(mob/user)
- ..(user)
- to_chat(user, "It reads: \"[message]\"")
+ . = ..()
+ . += "It reads: \"[message]\""
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm
index b0714331005..7f89c1e0705 100644
--- a/code/game/objects/effects/glowshroom.dm
+++ b/code/game/objects/effects/glowshroom.dm
@@ -33,7 +33,7 @@
/obj/structure/glowshroom/examine(mob/user)
. = ..()
- to_chat(user, "This is a [generation]\th generation [name]!")
+ . += "This is a [generation]\th generation [name]!"
/obj/structure/glowshroom/Destroy()
QDEL_NULL(myseed)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index d7999bdc631..654ae9a8b56 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -157,10 +157,6 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
else
return
-/obj/item/water_act(volume, temperature, source, method = TOUCH)
- . = ..()
- extinguish()
-
/obj/item/verb/move_to_top()
set name = "Move To Top"
set category = null
@@ -175,7 +171,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
src.loc = T
-/obj/item/examine(mob/user, var/distance = -1)
+/obj/item/examine(mob/user)
var/size
switch(src.w_class)
if(WEIGHT_CLASS_TINY)
@@ -191,7 +187,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
if(WEIGHT_CLASS_GIGANTIC)
size = "gigantic"
- . = ..(user, distance, "", "It is a [size] item.")
+ . = ..(user, "", "It is a [size] item.")
if(user.research_scanner) //Mob has a research scanner active.
var/msg = "*--------*
"
@@ -212,7 +208,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
else
msg += "No extractable materials detected.
"
msg += "*--------*"
- to_chat(user, msg)
+ . += msg
/obj/item/burn()
if(!QDELETED(src))
@@ -499,7 +495,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
to_chat(user, "You're going to need to remove that mask/helmet/glasses first!")
return
- if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/carbon/slime))//Aliens don't have eyes./N slimes also don't have eyes!
+ if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/simple_animal/slime))//Aliens don't have eyes./N slimes also don't have eyes!
to_chat(user, "You cannot locate any eyes on this creature!")
return
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 1f7ad5c132b..4d27e5d175b 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -111,7 +111,7 @@
return
playsound(loc, 'sound/items/eatfood.ogg', 50, 0)
to_chat(user, "You take a [huffable ? "huff" : "bite"] of the [name]. Delicious!")
- user.nutrition += 5
+ user.adjust_nutrition(5)
if(uses)
uses -= 5
if(uses <= 0)
diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm
index f331ff72f94..e9cb80f398c 100644
--- a/code/game/objects/items/devices/lightreplacer.dm
+++ b/code/game/objects/items/devices/lightreplacer.dm
@@ -68,8 +68,8 @@
/obj/item/lightreplacer/examine(mob/user)
- ..()
- to_chat(user, status_string())
+ . = ..()
+ . += status_string()
/obj/item/lightreplacer/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/stack/sheet/glass))
diff --git a/code/game/objects/items/devices/pipe_painter.dm b/code/game/objects/items/devices/pipe_painter.dm
index 35074718862..69beb04f67c 100644
--- a/code/game/objects/items/devices/pipe_painter.dm
+++ b/code/game/objects/items/devices/pipe_painter.dm
@@ -29,5 +29,5 @@
mode = input("Which colour do you want to use?", "Pipe Painter", mode) in modes
/obj/item/pipe_painter/examine(mob/user)
- ..(user)
- to_chat(user, "It is in [mode] mode.")
+ . = ..()
+ . += "It is in [mode] mode."
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index bf7ee23eed0..0ef3b0b0728 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -48,12 +48,11 @@
/obj/item/radio/headset/list_channels(var/mob/user)
return list_secure_channels()
-/obj/item/radio/headset/examine(mob/user, var/distance = -1)
- if(!(..(user, 1) && radio_desc))
- return
-
- to_chat(user, "The following channels are available:")
- to_chat(user, radio_desc)
+/obj/item/radio/headset/examine(mob/user)
+ . = ..()
+ if(in_range(src, user) && radio_desc)
+ . += "The following channels are available:"
+ . += radio_desc
/obj/item/radio/headset/handle_message_mode(mob/living/M as mob, list/message_pieces, channel)
if(channel == "special")
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 73c5dc8b41f..aab926f768e 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -595,14 +595,13 @@ var/global/list/default_medbay_channels = list(
return null
-/obj/item/radio/examine(mob/user, var/distance = -1)
- . = ..(user, distance)
- if((in_range(src, user) || loc == user))
+/obj/item/radio/examine(mob/user)
+ . = ..()
+ if(in_range(src, user) || loc == user)
if(b_stat)
- user.show_message("\the [src] can be attached and modified!")
+ . += "\the [src] can be attached and modified!"
else
- user.show_message("\the [src] can not be modified or attached!")
- return .
+ . += "\the [src] can not be modified or attached!"
/obj/item/radio/attackby(obj/item/W as obj, mob/user as mob, params)
..()
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 841850ee418..dbe22162b57 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -339,8 +339,8 @@ proc/healthscan(mob/user, mob/living/M, mode = 1, upgraded = FALSE)
var/accuracy // 0 is the best accuracy.
/obj/item/analyzer/examine(mob/user)
- .=..()
- to_chat(user, "Alt-click [src] to activate the barometer function.")
+ . = ..()
+ . += "Alt-click [src] to activate the barometer function."
/obj/item/analyzer/attack_self(mob/user as mob)
@@ -547,39 +547,46 @@ proc/healthscan(mob/user, mob/living/M, mode = 1, upgraded = FALSE)
throw_range = 7
materials = list(MAT_METAL=30, MAT_GLASS=20)
-/obj/item/slime_scanner/attack(mob/living/M as mob, mob/living/user as mob)
- slime_scan(M, user)
-
-/proc/slime_scan(mob/living/carbon/slime/M, mob/living/user)
- if(!isslime(M))
- user.show_message("This device can only scan slimes!", 1)
+/obj/item/slime_scanner/attack(mob/living/M, mob/living/user)
+ if(user.incapacitated() || user.eye_blind)
return
- var/mob/living/carbon/slime/T = M
- user.show_message("Slime scan results:", 1)
- user.show_message(text("[T.colour] [] slime", T.is_adult ? "adult" : "baby"), 1)
- user.show_message(text("Nutrition: [T.nutrition]/[]", T.get_max_nutrition()), 1)
+ if(!isslime(M))
+ to_chat(user, "This device can only scan slimes!")
+ return
+ var/mob/living/simple_animal/slime/T = M
+ slime_scan(T, user)
+
+/proc/slime_scan(mob/living/simple_animal/slime/T, mob/living/user)
+ to_chat(user, "========================")
+ to_chat(user, "Slime scan results:")
+ to_chat(user, "[T.colour] [T.is_adult ? "adult" : "baby"] slime")
+ to_chat(user, "Nutrition: [T.nutrition]/[T.get_max_nutrition()]")
if(T.nutrition < T.get_starve_nutrition())
- user.show_message("Warning: slime is starving!", 1)
+ to_chat(user, "Warning: slime is starving!")
else if(T.nutrition < T.get_hunger_nutrition())
- user.show_message("Warning: slime is hungry", 1)
- user.show_message("Electric change strength: [T.powerlevel]", 1)
- user.show_message("Health: [T.health]", 1)
+ to_chat(user, "Warning: slime is hungry")
+ to_chat(user, "Electric change strength: [T.powerlevel]")
+ to_chat(user, "Health: [round(T.health/T.maxHealth,0.01)*100]%")
if(T.slime_mutation[4] == T.colour)
- user.show_message("This slime does not evolve any further.", 1)
+ to_chat(user, "This slime does not evolve any further.")
else
if(T.slime_mutation[3] == T.slime_mutation[4])
if(T.slime_mutation[2] == T.slime_mutation[1])
- user.show_message("Possible mutation: [T.slime_mutation[3]]", 1)
- user.show_message("Genetic destability: [T.mutation_chance/2]% chance of mutation on splitting", 1)
+ to_chat(user, "Possible mutation: [T.slime_mutation[3]]")
+ to_chat(user, "Genetic destability: [T.mutation_chance/2] % chance of mutation on splitting")
else
- user.show_message("Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]] (x2)", 1)
- user.show_message("Genetic destability: [T.mutation_chance]% chance of mutation on splitting", 1)
+ to_chat(user, "Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]] (x2)")
+ to_chat(user, "Genetic destability: [T.mutation_chance] % chance of mutation on splitting")
else
- user.show_message("Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]], [T.slime_mutation[4]]", 1)
- user.show_message("Genetic destability: [T.mutation_chance]% chance of mutation on splitting", 1)
+ to_chat(user, "Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]], [T.slime_mutation[4]]")
+ to_chat(user, "Genetic destability: [T.mutation_chance] % chance of mutation on splitting")
if(T.cores > 1)
- user.show_message("Anomalous slime core amount detected", 1)
- user.show_message("Growth progress: [T.amount_grown]/10", 1)
+ to_chat(user, "Multiple cores detected")
+ to_chat(user, "Growth progress: [T.amount_grown]/[SLIME_EVOLUTION_THRESHOLD]")
+ if(T.effectmod)
+ to_chat(user, "Core mutation in progress: [T.effectmod]")
+ to_chat(user, "Progress in core mutation: [T.applied] / [SLIME_EXTRACT_CROSSING_REQUIRED]")
+ to_chat(user, "========================")
/obj/item/bodyanalyzer
name = "handheld body analyzer"
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index d3d0a2fe6bb..ed8dfebba23 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -26,8 +26,9 @@
return ..()
/obj/item/taperecorder/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "The wire panel is [open_panel ? "opened" : "closed"].")
+ . = ..()
+ if(in_range(user, src))
+ . += "The wire panel is [open_panel ? "opened" : "closed"]."
/obj/item/taperecorder/attackby(obj/item/I, mob/user)
diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm
index a738b6f03d4..61561131219 100644
--- a/code/game/objects/items/devices/traitordevices.dm
+++ b/code/game/objects/items/devices/traitordevices.dm
@@ -31,11 +31,11 @@ effective or pretty fucking useless.
var/max_uses = 5
/obj/item/batterer/examine(mob/user)
- ..(user)
+ . = ..()
if(times_used >= max_uses)
- to_chat(user, "[src] is out of charge.")
+ . += "[src] is out of charge."
if(times_used < max_uses)
- to_chat(user, "[src] has [max_uses-times_used] charges left.")
+ . += "[src] has [max_uses-times_used] charges left."
/obj/item/batterer/attack_self(mob/living/carbon/user, flag = 0, emp = 0)
if(!user)
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 57c9fb4f074..a4141a7a58a 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -49,12 +49,13 @@
return ..()
/obj/item/stack/examine(mob/user)
- if(..(user, 1))
+ . = ..()
+ if(in_range(user, src))
if(singular_name)
- to_chat(user, "There are [amount] [singular_name]\s in the stack.")
+ . += "There are [amount] [singular_name]\s in the stack."
else
- to_chat(user, "There are [amount] [name]\s in the stack.")
- to_chat(user,"Alt-click to take a custom amount.")
+ . += "There are [amount] [name]\s in the stack."
+ . +="Alt-click to take a custom amount."
/obj/item/stack/proc/add(newamount)
amount += newamount
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 905fada215e..71d5e36badf 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -642,13 +642,14 @@ obj/item/toy/cards/singlecard
obj/item/toy/cards/singlecard/examine(mob/user)
- if(..(user, 0))
+ . = ..()
+ if(get_dist(user, src) <= 0)
if(ishuman(user))
var/mob/living/carbon/human/cardUser = user
if(cardUser.get_item_by_slot(slot_l_hand) == src || cardUser.get_item_by_slot(slot_r_hand) == src)
cardUser.visible_message("[cardUser] checks [cardUser.p_their()] card.", "The card reads: [src.cardname]")
else
- to_chat(cardUser, "You need to have the card in your hand to check it.")
+ . += "You need to have the card in your hand to check it."
obj/item/toy/cards/singlecard/verb/Flip()
@@ -1471,9 +1472,9 @@ obj/item/toy/cards/deck/syndicate/black
fake_bullets = rand(2, 7)
/obj/item/toy/russian_revolver/trick_revolver/examine(mob/user) //Sneaky sneaky
- ..()
- to_chat(user, "Has [fake_bullets] round\s remaining.")
- to_chat(user, "[fake_bullets] of those are live rounds.")
+ . = ..()
+ . += "Has [fake_bullets] round\s remaining."
+ . += "[fake_bullets] of those are live rounds."
/obj/item/toy/russian_revolver/trick_revolver/post_shot(user)
to_chat(user, "[src] did look pretty dodgey!")
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index a8890e1636e..733e3f7e0bd 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -83,8 +83,8 @@ GLOBAL_LIST_INIT(rcd_door_types, list(
/obj/item/rcd/examine(mob/user)
. = ..()
- to_chat(user, "MATTER: [matter]/[max_matter] matter-units.")
- to_chat(user, "MODE: [mode].")
+ . += "MATTER: [matter]/[max_matter] matter-units."
+ . += "MODE: [mode]."
/obj/item/rcd/Destroy()
QDEL_NULL(spark_system)
diff --git a/code/game/objects/items/weapons/RCL.dm b/code/game/objects/items/weapons/RCL.dm
index befe979078c..10e52fc716a 100644
--- a/code/game/objects/items/weapons/RCL.dm
+++ b/code/game/objects/items/weapons/RCL.dm
@@ -57,9 +57,9 @@
..()
/obj/item/twohanded/rcl/examine(mob/user)
- ..()
+ . = ..()
if(loaded)
- to_chat(user, "It contains [loaded.amount]/[max_amount] cables.")
+ . += "It contains [loaded.amount]/[max_amount] cables."
/obj/item/twohanded/rcl/Destroy()
QDEL_NULL(loaded)
diff --git a/code/game/objects/items/weapons/bee_briefcase.dm b/code/game/objects/items/weapons/bee_briefcase.dm
index f370e186bcf..157868e3db4 100644
--- a/code/game/objects/items/weapons/bee_briefcase.dm
+++ b/code/game/objects/items/weapons/bee_briefcase.dm
@@ -23,12 +23,12 @@
return ..()
/obj/item/bee_briefcase/examine(mob/user)
- ..()
+ . = ..()
if(loc == user)
if(bees_left)
- to_chat(user, "There are [bees_left] bees still inside in briefcase!")
+ . += "There are [bees_left] bees still inside in briefcase!"
else
- to_chat(user, "The bees are gone... Colony collapse disorder?")
+ . += "The bees are gone... Colony collapse disorder?"
/obj/item/bee_briefcase/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers/syringe))
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 8452d8bd987..400759e845a 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -120,20 +120,21 @@
SetOwnerInfo(H)
/obj/item/card/id/examine(mob/user)
- if(..(user, 1))
+ . = ..()
+ if(in_range(user, src))
show(usr)
else
- to_chat(user, "It is too far away.")
+ . += "It is too far away."
if(guest_pass)
- to_chat(user, "There is a guest pass attached to this ID card")
+ . += "There is a guest pass attached to this ID card"
if(world.time < guest_pass.expiration_time)
- to_chat(user, "It expires at [station_time_timestamp("hh:mm:ss", guest_pass.expiration_time)].")
+ . += "It expires at [station_time_timestamp("hh:mm:ss", guest_pass.expiration_time)]."
else
- to_chat(user, "It expired at [station_time_timestamp("hh:mm:ss", guest_pass.expiration_time)].")
- to_chat(user, "It grants access to following areas:")
+ . += "It expired at [station_time_timestamp("hh:mm:ss", guest_pass.expiration_time)]."
+ . += "It grants access to following areas:"
for(var/A in guest_pass.temp_access)
- to_chat(user, "[get_access_desc(A)].")
- to_chat(user, "Issuing reason: [guest_pass.reason].")
+ . += "[get_access_desc(A)]."
+ . += "Issuing reason: [guest_pass.reason]."
/obj/item/card/id/proc/show(mob/user as mob)
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper)
@@ -143,7 +144,6 @@
popup.set_content(dat)
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
- return
/obj/item/card/id/attack_self(mob/user as mob)
user.visible_message("[user] shows you: [bicon(src)] [src.name]. The assignment on the card: [src.assignment]",\
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index 771d7bc2330..23e81e3c41d 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -45,8 +45,8 @@
update_charge()
/obj/item/defibrillator/examine(mob/user)
- ..(user)
- to_chat(user, "Ctrl-click to remove the paddles from the defibrillator.")
+ . = ..()
+ . += "Ctrl-click to remove the paddles from the defibrillator."
/obj/item/defibrillator/proc/update_power()
if(bcell)
diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm
index d27fd10ef87..2a7ad987f47 100644
--- a/code/game/objects/items/weapons/extinguisher.dm
+++ b/code/game/objects/items/weapons/extinguisher.dm
@@ -41,7 +41,7 @@
/obj/item/extinguisher/examine(mob/user)
. = ..()
- to_chat(user, "The safety is [safety ? "on" : "off"].")
+ . += "The safety is [safety ? "on" : "off"]."
/obj/item/extinguisher/New()
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index 3e41009bf68..298ce493b14 100644
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -142,9 +142,9 @@
update_icon()
/obj/item/flamethrower/examine(mob/user)
- ..()
+ . = ..()
if(ptank)
- to_chat(user, "[src] has \a [ptank] attached. Alt-click to remove it.")
+ . += "[src] has \a [ptank] attached. Alt-click to remove it."
/obj/item/flamethrower/proc/toggle_igniter(mob/user)
if(!ptank)
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index 10bbb7c7cb5..91c6252d9b2 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -37,7 +37,7 @@
return ..()
/obj/item/grenade/chem_grenade/examine(mob/user)
- ..(user)
+ . = ..()
display_timer = (stage == READY && !nadeassembly) //show/hide the timer based on assembly state
diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm
index ca6177c04fa..b58330a248b 100644
--- a/code/game/objects/items/weapons/grenades/ghettobomb.dm
+++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm
@@ -62,5 +62,5 @@
qdel(src)
/obj/item/grenade/iedcasing/examine(mob/user)
- ..()
- to_chat(user, "You can't tell when it will explode!")
+ . = ..()
+ . += "You can't tell when it will explode!"
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index f3a5a4c0886..414fffdfc7e 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -54,12 +54,12 @@
/obj/item/grenade/examine(mob/user)
- ..(user)
+ . = ..()
if(display_timer)
if(det_time > 1)
- to_chat(user, "The timer is set to [det_time/10] second\s.")
+ . += "The timer is set to [det_time/10] second\s."
else
- to_chat(user, "\The [src] is set for instant detonation.")
+ . += "\The [src] is set for instant detonation."
/obj/item/grenade/attack_self(mob/user as mob)
if(!active)
diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm
index 0de138805f1..33d72c1ebb5 100644
--- a/code/game/objects/items/weapons/holy_weapons.dm
+++ b/code/game/objects/items/weapons/holy_weapons.dm
@@ -47,7 +47,7 @@
/obj/item/nullrod/examine(mob/living/user)
. = ..()
if(sanctify_force)
- to_chat(user, "It bears the inscription: 'Sanctified weapon of the inquisitors. Only the worthy may wield. Nobody shall expect us.'")
+ . += "It bears the inscription: 'Sanctified weapon of the inquisitors. Only the worthy may wield. Nobody shall expect us.'"
/obj/item/nullrod/proc/reskin_holy_weapon(mob/M)
var/list/holy_weapons_list = typesof(/obj/item/nullrod)
@@ -619,6 +619,7 @@
/obj/item/nullrod/missionary_staff/proc/do_convert(mob/living/carbon/human/target, mob/living/carbon/human/missionary)
var/convert_duration = 6000 //10 min
+
if(!target || !ishuman(target) || !missionary || !ishuman(missionary))
return
if(ismindslave(target) || target.mind.zealot_master) //mindslaves and zealots override the staff because the staff is just a temporary mindslave
diff --git a/code/game/objects/items/weapons/implants/implant_traitor.dm b/code/game/objects/items/weapons/implants/implant_traitor.dm
index 16d8943567d..743488e4354 100644
--- a/code/game/objects/items/weapons/implants/implant_traitor.dm
+++ b/code/game/objects/items/weapons/implants/implant_traitor.dm
@@ -17,64 +17,65 @@
return dat
/obj/item/implant/traitor/implant(mob/M, mob/user)
+ if(!M.mind) // If the target is catatonic or doesn't have a mind, don't let them use it
+ to_chat(user, "This person doesn't have a mind for you to slave!")
+ return 0
+
if(!activated) //So you can't just keep taking it out and putting it back into other people.
- var/mob/living/carbon/human/H = M
- if(ismindslave(H))
- H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.")
+ var/mob/living/carbon/human/mindslave_target = M
+ if(ismindslave(mindslave_target))
+ mindslave_target.visible_message("[mindslave_target] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.")
qdel(src)
return -1
if(..())
var/list/implanters
- var/ref = "\ref[user.mind]"
- if(!ishuman(M))
+ if(!ishuman(mindslave_target))
return 0
- if(!M.mind)
+ if(!mindslave_target.mind)
return 0
- if(M == user)
+ if(mindslave_target == user)
to_chat(user, "Making yourself loyal to yourself was a great idea! Perhaps even the best idea ever! Actually, you just feel like an idiot.")
if(isliving(user))
var/mob/living/L = user
L.adjustBrainLoss(20)
- removed(M)
+ removed(mindslave_target)
+ qdel(src)
+ return -1
+ if(ismindshielded(mindslave_target))
+ mindslave_target.visible_message("[mindslave_target] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.")
+ removed(mindslave_target)
qdel(src)
return -1
- if(ismindshielded(H))
- H.visible_message("[H] seems to resist the implant!", "You feel a strange sensation in your head that quickly dissipates.")
- removed(M)
- qdel(src)
- return -1
- H.implanting = 1
- to_chat(H, "You feel completely loyal to [user.name].")
+
+ mindslave_target.implanting = 1
+ to_chat(mindslave_target, "You feel completely loyal to [user.name].")
if(!(user.mind in SSticker.mode.implanter))
- SSticker.mode.implanter[ref] = list()
- implanters = SSticker.mode.implanter[ref]
- implanters.Add(H.mind)
- SSticker.mode.implanted.Add(H.mind)
- SSticker.mode.implanted[H.mind] = user.mind
- //SSticker.mode.implanter[user.mind] += H.mind
- SSticker.mode.implanter[ref] = implanters
- SSticker.mode.traitors += H.mind
- H.mind.special_role = SPECIAL_ROLE_TRAITOR
- to_chat(H, "You're now completely loyal to [user.name]! You now must lay down your life to protect [user.p_them()] and assist in [user.p_their()] goals at any cost.")
+ SSticker.mode.implanter[user.mind] = list()
+ implanters = SSticker.mode.implanter[user.mind]
+ implanters.Add(mindslave_target.mind)
+ SSticker.mode.implanted.Add(mindslave_target.mind)
+ SSticker.mode.implanted[mindslave_target.mind] = user.mind
+ SSticker.mode.implanter[user.mind] = implanters
+ SSticker.mode.traitors += mindslave_target.mind
+
+ to_chat(mindslave_target, "You're now completely loyal to [user.name]! You now must lay down your life to protect [user.p_them()] and assist in [user.p_their()] goals at any cost.")
+
var/datum/objective/protect/mindslave/MS = new
- MS.owner = H.mind
+ MS.owner = mindslave_target.mind
MS.target = user.mind
MS.explanation_text = "Obey every order from and protect [user.real_name], the [user.mind.assigned_role == user.mind.special_role ? (user.mind.special_role) : (user.mind.assigned_role)]."
- H.mind.objectives += MS
- for(var/datum/objective/objective in H.mind.objectives)
- to_chat(H, "Objective #1: [objective.explanation_text]")
+
+ var/datum/antagonist/mindslave/S = new()
+ S.add_objective(MS)
+ mindslave_target.mind.add_antag_datum(S)
- SSticker.mode.update_traitor_icons_added(user.mind)
- SSticker.mode.update_traitor_icons_added(H.mind)//handles datahuds/observerhuds
+ var/datum/mindslaves/slaved = user.mind.som
+ mindslave_target.mind.som = slaved
+ slaved.serv += mindslave_target
+ slaved.add_serv_hud(user.mind, "master") //handles master servent icons
+ slaved.add_serv_hud(mindslave_target.mind, "mindslave")
- if(user.mind.som)//do not add if not a traitor..and you just picked up an implanter in the hall...
- var/datum/mindslaves/slaved = user.mind.som
- H.mind.som = slaved
- slaved.serv += H
- slaved.add_serv_hud(user.mind, "master") //handles master servent icons
- slaved.add_serv_hud(H.mind, "mindslave")
-
- log_admin("[key_name(user)] has mind-slaved [key_name(H)].")
+ log_admin("[key_name(user)] has mind-slaved [key_name(mindslave_target)].")
activated = 1
if(jobban_isbanned(M, ROLE_SYNDICATE))
SSticker.mode.replace_jobbanned_player(M, ROLE_SYNDICATE)
@@ -83,6 +84,7 @@
/obj/item/implant/traitor/removed(mob/target)
if(..())
- SSticker.mode.remove_traitor_mind(target.mind)
+ target.mind.remove_antag_datum(/datum/antagonist/mindslave)
+ to_chat(target, "You are no longer a mindslave: you have complete and free control of your own faculties, once more!")
return 1
- return 0
\ No newline at end of file
+ return 0
diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm
index cef14d28796..5727fe08cd0 100644
--- a/code/game/objects/items/weapons/implants/implantchair.dm
+++ b/code/game/objects/items/weapons/implants/implantchair.dm
@@ -79,7 +79,7 @@
return
var/mob/M = G.affecting
if(M.has_buckled_mobs())
- to_chat(usr, "[M] will not fit into [src] because [M.p_they()] [M.p_have()] a slime latched onto [M.p_their()] head.")
+ to_chat(user, "[M] will not fit into [src] because [M.p_they()] [M.p_have()] a slime latched onto [M.p_their()] head.")
return
if(put_mob(M))
qdel(G)
diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm
index c0e43882d6c..3d18b2e0109 100644
--- a/code/game/objects/items/weapons/kitchen.dm
+++ b/code/game/objects/items/weapons/kitchen.dm
@@ -151,12 +151,11 @@
w_class = WEIGHT_CLASS_NORMAL
/obj/item/kitchen/knife/butcher/meatcleaver
- name = "Meat Cleaver"
+ name = "meat cleaver"
icon_state = "mcleaver"
item_state = "butch"
- desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown-by-products."
- force = 25.0
- throwforce = 15.0
+ force = 25
+ throwforce = 15
/obj/item/kitchen/knife/combat
name = "combat knife"
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index cb99b0ac690..d18fc636794 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -332,10 +332,10 @@
add_fingerprint(user)
/obj/item/melee/energy/cleaving_saw/examine(mob/user)
- ..()
- to_chat(user, "It is [active ? "open, will cleave enemies in a wide arc and deal additional damage to fauna":"closed, and can be used for rapid consecutive attacks that cause fauna to bleed"].
\
+ . = ..()
+ . += "It is [active ? "open, will cleave enemies in a wide arc and deal additional damage to fauna":"closed, and can be used for rapid consecutive attacks that cause fauna to bleed"].
\
Both modes will build up existing bleed effects, doing a burst of high damage if the bleed is built up high enough.
\
- Transforming it immediately after an attack causes the next attack to come out faster.")
+ Transforming it immediately after an attack causes the next attack to come out faster."
/obj/item/melee/energy/cleaving_saw/suicide_act(mob/user)
user.visible_message("[user] is [active ? "closing [src] on [user.p_their()] neck" : "opening [src] into [user.p_their()] chest"]! It looks like [user.p_theyre()] trying to commit suicide!")
diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm
index a92deece906..69e11a533fd 100644
--- a/code/game/objects/items/weapons/mop.dm
+++ b/code/game/objects/items/weapons/mop.dm
@@ -106,8 +106,8 @@
reagents.add_reagent(refill_reagent, refill_rate)
/obj/item/mop/advanced/examine(mob/user)
- ..()
- to_chat(user, "The condenser switch is set to [refill_enabled ? "ON" : "OFF"].")
+ . = ..()
+ . += "The condenser switch is set to [refill_enabled ? "ON" : "OFF"]."
/obj/item/mop/advanced/Destroy()
if(refill_enabled)
diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm
index b5d608d51f7..6a2ee5635d7 100644
--- a/code/game/objects/items/weapons/pneumaticCannon.dm
+++ b/code/game/objects/items/weapons/pneumaticCannon.dm
@@ -23,16 +23,14 @@
return ..()
/obj/item/pneumatic_cannon/examine(mob/user)
- ..()
+ . = ..()
if(!in_range(user, src))
- to_chat(user, "You'll need to get closer to see any more.")
- return
- for(var/obj/item/I in loadedItems)
- spawn(0)
- to_chat(user, "[bicon(I)] It has \the [I] loaded.")
- if(tank)
- to_chat(user, "[bicon(tank)] It has \the [tank] mounted onto it.")
-
+ . += "You'll need to get closer to see any more."
+ else
+ if(tank)
+ . += "[bicon(tank)] It has \the [tank] mounted onto it."
+ for(var/obj/item/I in loadedItems)
+ . += "[bicon(I)] It has \the [I] loaded."
/obj/item/pneumatic_cannon/attackby(obj/item/W, mob/user, params)
..()
diff --git a/code/game/objects/items/weapons/powerfist.dm b/code/game/objects/items/weapons/powerfist.dm
index fe849371f05..4aab2c25d22 100644
--- a/code/game/objects/items/weapons/powerfist.dm
+++ b/code/game/objects/items/weapons/powerfist.dm
@@ -23,12 +23,11 @@
return ..()
/obj/item/melee/powerfist/examine(mob/user)
- ..()
+ . = ..()
if(!in_range(user, src))
- to_chat(user, "You'll need to get closer to see any more.")
- return
- if(tank)
- to_chat(user, "[bicon(tank)] It has [tank] mounted onto it.")
+ . += "You'll need to get closer to see any more."
+ else if(tank)
+ . += "[bicon(tank)] It has [tank] mounted onto it."
/obj/item/melee/powerfist/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/tank))
diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm
index c680b93cce8..1b2b9c6f21c 100644
--- a/code/game/objects/items/weapons/scrolls.dm
+++ b/code/game/objects/items/weapons/scrolls.dm
@@ -85,6 +85,9 @@
if(user && user.buckled)
user.buckled.unbuckle_mob(user, force = TRUE)
+ if(user && user.has_buckled_mobs())
+ user.unbuckle_all_mobs(force = TRUE)
+
var/list/tempL = L
var/attempt = null
var/success = 0
diff --git a/code/game/objects/items/weapons/soap.dm b/code/game/objects/items/weapons/soap.dm
index 912212d19c7..20cd0eb1e28 100644
--- a/code/game/objects/items/weapons/soap.dm
+++ b/code/game/objects/items/weapons/soap.dm
@@ -31,7 +31,7 @@
if(muncher && isdrask(muncher))
to_chat(user, "You take a bite of the [name]. Delicious!")
playsound(user.loc, 'sound/items/eatfood.ogg', 50, 0)
- user.nutrition += 2
+ user.adjust_nutrition(2)
else if(istype(target,/obj/effect/decal/cleanable))
user.visible_message("[user] begins to scrub \the [target.name] out with [src].")
if(do_after(user, cleanspeed, target = target) && target)
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index 765cdf35a59..63a19645346 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -29,20 +29,20 @@
/obj/item/storage/backpack/examine(mob/user)
var/space_used = 0
- if(!..(user, 1))
- return
- for(var/obj/item/I in contents)
- space_used += I.w_class
- if(!space_used)
- to_chat(user, " [src] is empty.")
- else if(space_used <= max_combined_w_class*0.6)
- to_chat(user, " [src] still has plenty of remaining space.")
- else if(space_used <= max_combined_w_class*0.8)
- to_chat(user, " [src] is beginning to run out of space.")
- else if(space_used < max_combined_w_class)
- to_chat(user, " [src] doesn't have much space left.")
- else
- to_chat(user, " [src] is full.")
+ . = ..()
+ if(in_range(user, src))
+ for(var/obj/item/I in contents)
+ space_used += I.w_class
+ if(!space_used)
+ . += " [src] is empty."
+ else if(space_used <= max_combined_w_class*0.6)
+ . += " [src] still has plenty of remaining space."
+ else if(space_used <= max_combined_w_class*0.8)
+ . += " [src] is beginning to run out of space."
+ else if(space_used < max_combined_w_class)
+ . += " [src] doesn't have much space left."
+ else
+ . += " [src] is full."
/*
* Backpack Types
diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm
index 3b7aee036b9..664cc8229bd 100644
--- a/code/game/objects/items/weapons/storage/fancy.dm
+++ b/code/game/objects/items/weapons/storage/fancy.dm
@@ -26,15 +26,15 @@
return
/obj/item/storage/fancy/examine(mob/user)
- if(!..(user, 1))
- return
-
- if(contents.len <= 0)
- to_chat(user, "There are no [src.icon_type]s left in the box.")
- else if(contents.len == 1)
- to_chat(user, "There is one [src.icon_type] left in the box.")
- else
- to_chat(user, "There are [src.contents.len] [src.icon_type]s in the box.")
+ . = ..()
+ if(in_range(user, src))
+ var/len = LAZYLEN(contents)
+ if(len <= 0)
+ . += "There are no [src.icon_type]s left in the box."
+ else if(len == 1)
+ . += "There is one [src.icon_type] left in the box."
+ else
+ . += "There are [src.contents.len] [src.icon_type]s in the box."
diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm
index aeaa7991420..a91d1e10f62 100644
--- a/code/game/objects/items/weapons/storage/secure.dm
+++ b/code/game/objects/items/weapons/storage/secure.dm
@@ -28,8 +28,9 @@
max_combined_w_class = 14
/obj/item/storage/secure/examine(mob/user)
- if(..(user, 1))
- to_chat(user, text("The service panel is [open ? "open" : "closed"]."))
+ . = ..()
+ if(in_range(user, src))
+ . += "The service panel is [open ? "open" : "closed"]."
/obj/item/storage/secure/attackby(obj/item/W as obj, mob/user as mob, params)
if(locked)
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index 2a4083f673f..232d8384e45 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -74,13 +74,13 @@
icon_state = "[base_icon]"
/obj/item/melee/baton/examine(mob/user)
- ..(user)
+ . = ..()
if(isrobot(loc))
- to_chat(user, "This baton is drawing power directly from your own internal charge.")
+ . += "This baton is drawing power directly from your own internal charge."
if(bcell)
- to_chat(user, "The baton is [round(bcell.percent())]% charged.")
+ . += "The baton is [round(bcell.percent())]% charged."
if(!bcell)
- to_chat(user, "The baton does not have a power source installed.")
+ . += "The baton does not have a power source installed."
/obj/item/melee/baton/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/stock_parts/cell))
diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm
index 3ccc27db955..40376248d61 100644
--- a/code/game/objects/items/weapons/tanks/jetpack.dm
+++ b/code/game/objects/items/weapons/tanks/jetpack.dm
@@ -35,11 +35,9 @@
/obj/item/tank/jetpack/examine(mob/user)
- if(!..(user, 0))
- return
-
- if(air_contents.oxygen < 10)
- to_chat(user, "The meter on [src] indicates you are almost out of air!")
+ . = ..()
+ if(get_dist(user, src) <= 0 && air_contents.oxygen < 10)
+ . += "The meter on [src] indicates you are almost out of air!"
playsound(user, 'sound/effects/alert.ogg', 50, 1)
@@ -157,11 +155,9 @@
air_contents.carbon_dioxide = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
/obj/item/tank/jetpack/carbondioxide/examine(mob/user)
- if(!..(user, 0))
- return
-
- if(air_contents.carbon_dioxide < 10)
- to_chat(user, "The meter on [src] indicates you are almost out of air!")
+ . = ..()
+ if(get_dist(user, src) <= 0 && air_contents.carbon_dioxide < 10)
+ . += "The meter on [src] indicates you are almost out of air!"
playsound(user, 'sound/effects/alert.ogg', 50, 1)
/obj/item/tank/jetpack/suit
@@ -230,8 +226,7 @@
actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
/obj/item/tank/jetpack/rig/examine()
- to_chat(usr, "It's a jetpack. If you can see this, report it on the bug tracker.")
- return 0
+ . = list("It's a jetpack. If you can see this, report it on the bug tracker.")
/obj/item/tank/jetpack/rig/allow_thrust(num, mob/living/user)
if(!on)
diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm
index fc4f3438aa1..55b0225bc2d 100644
--- a/code/game/objects/items/weapons/tanks/tank_types.dm
+++ b/code/game/objects/items/weapons/tanks/tank_types.dm
@@ -23,10 +23,9 @@
air_contents.oxygen = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
/obj/item/tank/oxygen/examine(mob/user)
- if(..(user, 0))
- if(air_contents.oxygen < 10)
- to_chat(user, text("The meter on the [src.name] indicates you are almost out of air!"))
- //playsound(usr, 'sound/effects/alert.ogg', 50, 1)
+ . = ..()
+ if(get_dist(user, src) <= 0 && air_contents.oxygen < 10)
+ . += "The meter on [src] indicates you are almost out of air!"
obj/item/tank/oxygen/empty/New()
..()
@@ -72,10 +71,10 @@ obj/item/tank/oxygen/empty/New()
item_state = "air"
/obj/item/tank/air/examine(mob/user)
- if(..(user, 0))
- if(air_contents.oxygen < 1 && loc==usr)
- to_chat(user, "The meter on the [src.name] indicates you are almost out of air!")
- user << sound('sound/effects/alert.ogg')
+ . = ..()
+ if(get_dist(user, src) <= 0 && air_contents.oxygen < 1)
+ . += "The meter on [src] indicates you are almost out of air!"
+ playsound(user, 'sound/effects/alert.ogg', 50, 1)
/obj/item/tank/air/New()
..()
@@ -121,10 +120,10 @@ obj/item/tank/oxygen/empty/New()
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
/obj/item/tank/plasma/plasmaman/examine(mob/user)
- if(..(user, 0))
- if(air_contents.toxins < 0.2 && loc==usr)
- to_chat(user, text("The meter on the [src.name] indicates you are almost out of plasma!"))
- user << sound('sound/effects/alert.ogg')
+ . = ..()
+ if(get_dist(user, src) <= 0 && air_contents.toxins < 0.2)
+ . += "The meter on [src] indicates you are almost out of plasma!"
+ playsound(user, 'sound/effects/alert.ogg', 50, 1)
/obj/item/tank/plasma/plasmaman/belt
@@ -159,10 +158,10 @@ obj/item/tank/oxygen/empty/New()
air_contents.oxygen = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
/obj/item/tank/emergency_oxygen/examine(mob/user)
- if(..(user, 0))
- if(air_contents.oxygen < 0.2 && loc==usr)
- to_chat(user, text("The meter on the [src.name] indicates you are almost out of air!"))
- user << sound('sound/effects/alert.ogg')
+ . = ..()
+ if(get_dist(user, src) <= 0 && air_contents.oxygen < 0.2)
+ . += "The meter on [src] indicates you are almost out of air!"
+ playsound(user, 'sound/effects/alert.ogg', 50, 1)
obj/item/tank/emergency_oxygen/empty/New()
..()
@@ -215,10 +214,9 @@ obj/item/tank/emergency_oxygen/double/empty/New()
air_contents.nitrogen = (3*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C)
/obj/item/tank/nitrogen/examine(mob/user)
- if(..(user, 0))
- if(air_contents.nitrogen < 10)
- to_chat(user, text("The meter on the [src.name] indicates you are almost out of air!"))
- //playsound(usr, 'sound/effects/alert.ogg', 50, 1)
+ . = ..()
+ if(get_dist(user, src) <= 0 && air_contents.nitrogen < 10)
+ . += "The meter on the [src.name] indicates you are almost out of air!"
/obj/item/tank/emergency_oxygen/vox
name = "vox specialized nitrogen tank"
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index f4a99daecef..f85af5c093d 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -76,8 +76,7 @@
/obj/item/tank/examine(mob/user)
- if(!..(user, 0))
- return
+ . = ..()
var/obj/icon = src
if(istype(loc, /obj/item/assembly))
@@ -85,7 +84,7 @@
if(!in_range(src, user))
if(icon == src)
- to_chat(user, "It's \a [bicon(icon)][src]! If you want any more information you'll need to get closer.")
+ . += "It's \a [bicon(icon)][src]! If you want any more information you'll need to get closer."
return
var/celsius_temperature = air_contents.temperature-T0C
@@ -104,9 +103,7 @@
else
descriptive = "furiously hot"
- to_chat(user, "\The [bicon(icon)][src] feels [descriptive]")
-
- return
+ . += "\The [bicon(icon)][src] feels [descriptive]"
/obj/item/tank/blob_act(obj/structure/blob/B)
if(B && B.loc == loc)
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index 64e2d23dceb..bf861c5acb1 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -352,8 +352,9 @@
update_icon()
/obj/item/weldingtool/examine(mob/user)
- if(..(user, 0))
- to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].")
+ . = ..()
+ if(get_dist(user, src) <= 0)
+ . += "It contains [get_fuel()] unit\s of fuel out of [max_fuel]."
/obj/item/weldingtool/suicide_act(mob/user)
user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!")
diff --git a/code/game/objects/items/weapons/vending_items.dm b/code/game/objects/items/weapons/vending_items.dm
index 93dc3f1eaa4..aafebf7ef92 100644
--- a/code/game/objects/items/weapons/vending_items.dm
+++ b/code/game/objects/items/weapons/vending_items.dm
@@ -29,11 +29,11 @@
. = ..()
var/num = get_part_rating()
if (num == INFINITY)
- to_chat(user, "It's sealed tight, completely full of supplies.")
+ . += "It's sealed tight, completely full of supplies."
else if (num == 0)
- to_chat(user, "It's empty!")
+ . += "It's empty!"
else
- to_chat(user, "It can restock [num] item\s.")
+ . += "It can restock [num] item\s."
/obj/item/vending_refill/get_part_rating()
if (!products || !contraband || !premium)
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index a0a5d6b826b..ce08fc165ac 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -133,10 +133,10 @@
var/amt = max(0, ((force - (move_resist * MOVE_FORCE_CRUSH_RATIO)) / (move_resist * MOVE_FORCE_CRUSH_RATIO)) * 10)
take_damage(amt, BRUTE)
-/obj/attack_slime(mob/living/carbon/slime/user)
+/obj/attack_slime(mob/living/simple_animal/slime/user)
if(!user.is_adult)
return
- attack_generic(user, rand(10, 15), "melee", 1)
+ attack_generic(user, rand(10, 15), BRUTE, "melee", 1)
/obj/mech_melee_attack(obj/mecha/M)
M.do_attack_animation(src)
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 134a1fa56aa..d4d20c8c650 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -273,6 +273,10 @@ a {
user.set_machine(src)
onclose(user, "mtcomputer")
+/obj/water_act(volume, temperature, source, method = TOUCH)
+ . = ..()
+ extinguish()
+
/obj/singularity_pull(S, current_size)
..()
if(!anchored || current_size >= STAGE_FIVE)
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 0fb3619a56d..c6b481d576e 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -151,15 +151,15 @@
return 1
/obj/structure/examine(mob/user)
- ..()
+ . = ..()
if(!(resistance_flags & INDESTRUCTIBLE))
if(resistance_flags & ON_FIRE)
- to_chat(user, "It's on fire!")
+ . += "It's on fire!"
if(broken)
- to_chat(user, "It appears to be broken.")
+ . += "It appears to be broken."
var/examine_status = examine_status(user)
if(examine_status)
- to_chat(user, examine_status)
+ . += examine_status
/obj/structure/proc/examine_status(mob/user) //An overridable proc, mostly for falsewalls.
var/healthpercent = (obj_integrity/max_integrity) * 100
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index af1552de982..8945819e3aa 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -244,14 +244,13 @@ LINEN BINS
/obj/structure/bedsheetbin/examine(mob/user)
- ..(user)
+ . = ..()
if(amount < 1)
- to_chat(user, "There are no bed sheets in the bin.")
- return
- if(amount == 1)
- to_chat(user, "There is one bed sheet in the bin.")
- return
- to_chat(user, "There are [amount] bed sheets in the bin.")
+ . += "There are no bed sheets in the bin."
+ else if(amount == 1)
+ . += "There is one bed sheet in the bin."
+ else
+ . += "There are [amount] bed sheets in the bin."
/obj/structure/bedsheetbin/update_icon()
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 9080b7b1b9c..8c1e0011264 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -105,7 +105,7 @@
continue
if(istype(M, /mob/living/simple_animal/bot/mulebot))
continue
- if(M.buckled || M.anchored)
+ if(M.buckled || M.anchored || M.has_buckled_mobs())
continue
M.forceMove(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
index e7b2bf6df36..dea63a0d69d 100644
--- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
+++ b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
@@ -17,7 +17,7 @@
/obj/structure/closet/fireaxecabinet/examine(mob/user)
. = ..()
- to_chat(user, "Use a multitool to lock/unlock it.")
+ . += "Use a multitool to lock/unlock it."
/obj/structure/closet/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/living/user as mob) //Marker -Agouri
if(isrobot(user) || locked)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
index 0608eb64cbb..517732cdd11 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -40,6 +40,7 @@
new /obj/item/reagent_containers/food/drinks/mug/ce(src)
new /obj/item/organ/internal/cyberimp/eyes/meson(src)
new /obj/item/clothing/accessory/medal/engineering(src)
+ new /obj/item/holosign_creator/atmos(src)
/obj/structure/closet/secure_closet/engineering_electrical
diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm
index b1b674f1b30..07bc395f578 100644
--- a/code/game/objects/structures/displaycase.dm
+++ b/code/game/objects/structures/displaycase.dm
@@ -150,12 +150,12 @@ GLOBAL_LIST_INIT(captain_display_cases, list())
start_showpiece_type = /obj/item/gun/projectile/automatic/pistol
/obj/structure/displaycase/examine(mob/user)
- ..(user)
- to_chat(user, "Peering through the glass, you see that it contains:")
+ . = ..()
+ . += "Peering through the glass, you see that it contains:"
if(occupant)
- to_chat(user, "[bicon(occupant)] \A [occupant].")
+ . += "[bicon(occupant)] \A [occupant]."
else
- to_chat(user, "Nothing.")
+ . += "Nothing."
/obj/structure/displaycase/proc/dump()
if(occupant)
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index 24fa53a06a5..461f300ae4d 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -30,28 +30,28 @@
return ..()
/obj/structure/door_assembly/examine(mob/user)
- ..()
+ . = ..()
var/doorname = ""
if(created_name)
doorname = ", written on it is '[created_name]'"
switch(state)
if(AIRLOCK_ASSEMBLY_NEEDS_WIRES)
if(anchored)
- to_chat(user, "The anchoring bolts are wrenched in place, but the maintenance panel lacks wiring.")
+ . += "The anchoring bolts are wrenched in place, but the maintenance panel lacks wiring."
else
- to_chat(user, "The assembly is welded together, but the anchoring bolts are unwrenched.")
+ . += "The assembly is welded together, but the anchoring bolts are unwrenched."
if(AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS)
- to_chat(user, "The maintenance panel is wired, but the circuit slot is empty.")
+ . += "The maintenance panel is wired, but the circuit slot is empty."
if(AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER)
- to_chat(user, "The circuit is connected loosely to its slot, but the maintenance panel is unscrewed and open.")
+ . += "The circuit is connected loosely to its slot, but the maintenance panel is unscrewed and open."
if(!mineral && !glass && !noglass)
- to_chat(user, "There is a small paper placard on the assembly[doorname]. There are empty slots for glass windows and mineral covers.")
+ . += "There is a small paper placard on the assembly[doorname]. There are empty slots for glass windows and mineral covers."
else if(!mineral && glass && !noglass)
- to_chat(user, "There is a small paper placard on the assembly[doorname]. There are empty slots for mineral covers.")
+ . += "There is a small paper placard on the assembly[doorname]. There are empty slots for mineral covers."
else if(mineral && !glass && !noglass)
- to_chat(user, "There is a small paper placard on the assembly[doorname]. There are empty slots for glass windows.")
+ . += "There is a small paper placard on the assembly[doorname]. There are empty slots for glass windows."
else
- to_chat(user, "There is a small paper placard on the assembly[doorname].")
+ . += "There is a small paper placard on the assembly[doorname]."
/obj/structure/door_assembly/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pen))
diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm
index 303862ff66f..1bd5ef9546d 100644
--- a/code/game/objects/structures/extinguisher.dm
+++ b/code/game/objects/structures/extinguisher.dm
@@ -29,8 +29,8 @@
has_extinguisher = new/obj/item/extinguisher
/obj/structure/extinguisher_cabinet/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to [opened ? "close":"open"] it.")
+ . = ..()
+ . += "Alt-click to [opened ? "close":"open"] it."
/obj/structure/extinguisher_cabinet/AltClick(mob/living/user)
if(!istype(user) || user.incapacitated())
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 85dc1b5bcfa..1366194c01b 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -14,16 +14,16 @@
. = ..()
switch(state)
if(GIRDER_REINF)
- to_chat(user, "The support struts are screwed in place.")
+ . += "The support struts are screwed in place."
if(GIRDER_REINF_STRUTS)
- to_chat(user, "The support struts are unscrewed and the inner grille is intact.")
+ . += "The support struts are unscrewed and the inner grille is intact."
if(GIRDER_NORMAL)
if(can_displace)
- to_chat(user, "The bolts are lodged in place.")
+ . += "The bolts are lodged in place."
if(GIRDER_DISPLACED)
- to_chat(user, "The bolts are loosened, but the screws are holding [src] together.")
+ . += "The bolts are loosened, but the screws are holding [src] together."
if(GIRDER_DISASSEMBLED)
- to_chat(user, "[src] is disassembled! You probably shouldn't be able to see this examine message.")
+ . += "[src] is disassembled! You probably shouldn't be able to see this examine message."
/obj/structure/girder/proc/refundMetal(metalAmount) //refunds metal used in construction when deconstructed
for(var/i=0;i < metalAmount;i++)
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index ad219fd50be..6751fa8063a 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -54,11 +54,11 @@
update_icon()
/obj/structure/grille/examine(mob/user)
- ..()
+ . = ..()
if(anchored)
- to_chat(user, "It's secured in place with screws. The rods look like they could be cut through.")
+ . += "It's secured in place with screws. The rods look like they could be cut through."
if(!anchored)
- to_chat(user, "The anchoring screws are unscrewed. The rods look like they could be cut through.")
+ . += "The anchoring screws are unscrewed. The rods look like they could be cut through."
/obj/structure/grille/ratvar_act()
if(broken)
diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm
index 6d32aec248e..eba923d5ea4 100644
--- a/code/game/objects/structures/guillotine.dm
+++ b/code/game/objects/structures/guillotine.dm
@@ -33,7 +33,7 @@
return ..()
/obj/structure/guillotine/examine(mob/user)
- ..()
+ . = ..()
var/msg = ""
@@ -53,9 +53,7 @@
msg += "
"
msg += "Someone appears to be strapped in. You can help them out, or you can harm them by activating the guillotine."
- to_chat(user, msg)
-
- return msg
+ . += msg
/obj/structure/guillotine/attack_hand(mob/user)
add_fingerprint(user)
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index 0280e74d31f..e9b3b2610e5 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -41,48 +41,8 @@
/obj/structure/inflatable/CanAtmosPass(turf/T)
return !density
-/obj/structure/inflatable/ex_act(severity)
- switch(severity)
- if(1.0)
- qdel(src)
- return
- if(2.0)
- deflate(1)
- return
- if(3.0)
- if(prob(50))
- deflate(1)
- return
-
/obj/structure/inflatable/attack_hand(mob/user as mob)
add_fingerprint(user)
- return
-
-/obj/structure/inflatable/attack_generic(mob/user, damage = 0) //used by attack_alien, attack_animal, and attack_slime
- health -= damage
- if(health <= 0)
- user.visible_message("[user] tears open [src]!")
- deflate(1)
- else //for nicer text~
- user.visible_message("[user] tears at [src]!")
-
-/obj/structure/inflatable/attackby(obj/item/W as obj, mob/user as mob, params)
- if(!istype(W))
- return
- if(is_pointed(W))
- visible_message("[user] pierces [src] with [W]!")
- deflate(1)
- if(W.damtype == BRUTE || W.damtype == BURN)
- hit(W.force)
- ..()
- return
-
-/obj/structure/inflatable/proc/hit(var/damage, var/sound_effect = 1)
- health = max(0, health - damage)
- if(sound_effect)
- playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1)
- if(health <= 0)
- deflate(1)
/obj/structure/inflatable/AltClick()
if(usr.stat || usr.restrained())
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index d56e880280d..128c7181a10 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -22,11 +22,11 @@
QDEL_IN(LAT, 0)
/obj/structure/lattice/examine(mob/user)
- ..()
- deconstruction_hints(user)
+ . = ..()
+ . += deconstruction_hints(user)
/obj/structure/lattice/proc/deconstruction_hints(mob/user)
- to_chat(user, "The rods look like they could be cut. There's space for more rods or a tile.")
+ return "The rods look like they could be cut. There's space for more rods or a tile."
/obj/structure/lattice/attackby(obj/item/C, mob/user, params)
if(resistance_flags & INDESTRUCTIBLE)
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index c6eede2894c..d6346a7e01d 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -81,6 +81,7 @@
if(BURN)
playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, TRUE)
+
/obj/item/mounted/mirror
name = "mirror"
desc = "Some reflective glass ready to be hung on a wall. Don't break it!"
diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm
index f01cc8c41ca..948a39ba93e 100644
--- a/code/game/objects/structures/mop_bucket.dm
+++ b/code/game/objects/structures/mop_bucket.dm
@@ -21,8 +21,9 @@
return ..()
/obj/structure/mopbucket/examine(mob/user)
- if(..(user, 1))
- to_chat(usr, "[bicon(src)] [src] contains [reagents.total_volume] units of water left!")
+ . = ..()
+ if(in_range(user, src))
+ . += "[bicon(src)] [src] contains [reagents.total_volume] units of water left!"
/obj/structure/mopbucket/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/mop))
diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm
index 0e46e4ed1fa..5ea5d2fd42a 100644
--- a/code/game/objects/structures/plasticflaps.dm
+++ b/code/game/objects/structures/plasticflaps.dm
@@ -13,9 +13,9 @@
. = ..()
switch(state)
if(PLASTIC_FLAPS_NORMAL)
- to_chat(user, "[src] are screwed to the floor.")
+ . += "[src] are screwed to the floor."
if(PLASTIC_FLAPS_DETACHED)
- to_chat(user, "[src] are no longer screwed to the floor, and the flaps can be sliced apart.")
+ . += "[src] are no longer screwed to the floor, and the flaps can be sliced apart."
/obj/structure/plasticflaps/attackby(obj/item/W, mob/user, params)
add_fingerprint(user)
diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm
index 3a7a3e22b6b..1e289a7f27b 100644
--- a/code/game/objects/structures/safe.dm
+++ b/code/game/objects/structures/safe.dm
@@ -78,9 +78,9 @@ GLOBAL_LIST_EMPTY(safes)
/obj/structure/safe/examine(mob/user)
. = ..()
- to_chat(user, "This model appears to have [number_of_tumblers] tumblers.")
+ . += "This model appears to have [number_of_tumblers] tumblers."
if(open)
- to_chat(user, "The inside of the the door has numbers written on it: [get_combination()]")
+ . += "The inside of the the door has numbers written on it: [get_combination()]"
/obj/structure/safe/blob_act(obj/structure/blob/B)
return
diff --git a/code/game/objects/structures/spirit_board.dm b/code/game/objects/structures/spirit_board.dm
index b6f66350f1f..dc82b824e34 100644
--- a/code/game/objects/structures/spirit_board.dm
+++ b/code/game/objects/structures/spirit_board.dm
@@ -11,8 +11,8 @@
var/lastuser = null
/obj/structure/spirit_board/examine(mob/user)
- ..(user)
- to_chat(user, "[initial(desc)] The planchette is sitting at \"[planchette]\".")
+ . = ..()
+ . += "[initial(desc)] The planchette is sitting at \"[planchette]\"."
/obj/structure/spirit_board/attack_hand(mob/user as mob)
if(..())
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 9d17582e463..100744293fa 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -41,11 +41,11 @@
update_icon()
/obj/structure/table/examine(mob/user)
- ..()
- deconstruction_hints(user)
+ . = ..()
+ . += deconstruction_hints(user)
/obj/structure/table/proc/deconstruction_hints(mob/user)
- to_chat(user, "The top is screwed on, but the main bolts are also visible.")
+ return "The top is screwed on, but the main bolts are also visible."
/obj/structure/table/update_icon()
if(smooth && !flipped)
@@ -648,8 +648,8 @@
max_integrity = 20
/obj/structure/rack/examine(mob/user)
- ..()
- to_chat(user, "It's held together by a couple of bolts.")
+ . = ..()
+ . += "It's held together by a couple of bolts."
/obj/structure/rack/CanPass(atom/movable/mover, turf/target, height=0)
if(height==0)
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index 1124745d8b3..0eee91ee068 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -28,8 +28,8 @@
var/state = "01" //How far the door assembly has progressed
/obj/structure/windoor_assembly/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to rotate it clockwise.")
+ . = ..()
+ . += "Alt-click to rotate it clockwise."
obj/structure/windoor_assembly/New(loc, set_dir)
..()
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 779ccbd42f1..00ff1473e15 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -51,23 +51,23 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
var/hitsound = 'sound/effects/Glasshit.ogg'
/obj/structure/window/examine(mob/user)
- ..()
+ . = ..()
if(reinf)
if(anchored && state == WINDOW_SCREWED_TO_FRAME)
- to_chat(user, "The window is screwed to the frame.")
+ . += "The window is screwed to the frame."
else if(anchored && state == WINDOW_IN_FRAME)
- to_chat(user, "The window is unscrewed but pried into the frame.")
+ . += "The window is unscrewed but pried into the frame."
else if(anchored && state == WINDOW_OUT_OF_FRAME)
- to_chat(user, "The window is out of the frame, but could be pried in. It is screwed to the floor.")
+ . += "The window is out of the frame, but could be pried in. It is screwed to the floor."
else if(!anchored)
- to_chat(user, "The window is unscrewed from the floor, and could be deconstructed by wrenching.")
+ . += "The window is unscrewed from the floor, and could be deconstructed by wrenching."
else
if(anchored)
- to_chat(user, "The window is screwed to the floor.")
+ . += "The window is screwed to the floor."
else
- to_chat(user, "The window is unscrewed from the floor, and could be deconstructed by wrenching.")
+ . += "The window is unscrewed from the floor, and could be deconstructed by wrenching."
if(!anchored && !fulltile)
- to_chat(user, "Alt-click to rotate it.")
+ . += "Alt-click to rotate it."
/obj/structure/window/New(Loc, direct)
..()
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index 618a88174da..e2e2eced8f0 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -37,7 +37,7 @@
. = ..()
if(unfastened)
- to_chat(user, "It has been unfastened.")
+ . += "It has been unfastened."
/turf/simulated/floor/plating/attackby(obj/item/C, mob/user, params)
if(..())
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 25680f542f4..65b80597c72 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -56,21 +56,21 @@
//Appearance
/turf/simulated/wall/examine(mob/user)
- . = ..(user)
+ . = ..()
if(!damage)
- to_chat(user, "It looks fully intact.")
+ . += "It looks fully intact."
else
var/dam = damage / damage_cap
if(dam <= 0.3)
- to_chat(user, "It looks slightly damaged.")
+ . += "It looks slightly damaged."
else if(dam <= 0.6)
- to_chat(user, "It looks moderately damaged.")
+ . += "It looks moderately damaged."
else
- to_chat(user, "It looks heavily damaged.")
+ . += "It looks heavily damaged."
if(rotting)
- to_chat(user, "There is fungus growing on [src].")
+ . += "There is fungus growing on [src]."
/turf/simulated/wall/proc/update_icon()
if(!damage_overlays[1]) //list hasn't been populated
diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm
index 32851c601c3..f58d5dd60ad 100644
--- a/code/game/turfs/simulated/walls_reinforced.dm
+++ b/code/game/turfs/simulated/walls_reinforced.dm
@@ -17,22 +17,22 @@
var/can_be_reinforced = 1
/turf/simulated/wall/r_wall/examine(mob/user)
- ..()
+ . = ..()
switch(d_state)
if(RWALL_INTACT)
- to_chat(user, "The outer grille is fully intact.")
+ . += "The outer grille is fully intact."
if(RWALL_SUPPORT_LINES)
- to_chat(user, "The outer grille has been cut, and the support lines are screwed securely to the outer cover.")
+ . += "The outer grille has been cut, and the support lines are screwed securely to the outer cover."
if(RWALL_COVER)
- to_chat(user, "The support lines have been unscrewed, and the metal cover is welded firmly in place.")
+ . += "The support lines have been unscrewed, and the metal cover is welded firmly in place."
if(RWALL_CUT_COVER)
- to_chat(user, "The metal cover has been sliced through, and is connected loosely to the girder.")
+ . += "The metal cover has been sliced through, and is connected loosely to the girder."
if(RWALL_BOLTS)
- to_chat(user, "The outer cover has been pried away, and the bolts anchoring the support rods are wrenched in place.")
+ . += "The outer cover has been pried away, and the bolts anchoring the support rods are wrenched in place."
if(RWALL_SUPPORT_RODS)
- to_chat(user, "The bolts anchoring the support rods have been loosened, but are still welded firmly to the girder.")
+ . += "The bolts anchoring the support rods have been loosened, but are still welded firmly to the girder."
if(RWALL_SHEATH)
- to_chat(user, "The support rods have been sliced through, and the outer sheath is connected loosely to the girder.")
+ . += "The support rods have been sliced through, and the outer sheath is connected loosely to the girder."
/turf/simulated/wall/r_wall/attackby(obj/item/I, mob/user, params)
if(try_repair(I, user, params))
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index 0b171dac199..50b53cc7dd9 100644
--- a/code/game/verbs/suicide.dm
+++ b/code/game/verbs/suicide.dm
@@ -209,7 +209,7 @@
adjustOxyLoss(max(175 - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
-/mob/living/carbon/slime/verb/suicide()
+/mob/living/simple_animal/slime/verb/suicide()
set hidden = 1
if(stat == 2)
to_chat(src, "You're already dead!")
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index cec31ffc2ac..fe487ae6431 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -113,9 +113,7 @@
Japanese Animes Mode
Egalitarian Station Mode
Summon Guns
- Summon Magic
- Summon Revolver Duel
- Summon Suicidal Revolver Duel
+ Summon Magic
Roll the Dice
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index a3d39396c06..d6228c1ec6e 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -345,7 +345,7 @@
var/mob/living/carbon/human/newmob = M.change_mob_type(/mob/living/carbon/human, null, null, delmob, 1)
if(posttransformoutfit && istype(newmob))
newmob.equipOutfit(posttransformoutfit)
- if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob, 1 )
+ if("slime") M.change_mob_type( /mob/living/simple_animal/slime , null, null, delmob, 1 )
if("monkey") M.change_mob_type( /mob/living/carbon/human/monkey , null, null, delmob, 1 )
if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob, 1 )
if("cat") M.change_mob_type( /mob/living/simple_animal/pet/cat , null, null, delmob, 1 )
@@ -1934,7 +1934,7 @@
H.reagents.add_reagent("ice", 40)
logmsg = "cold."
if("Hunger")
- H.nutrition = NUTRITION_LEVEL_CURSED
+ H.set_nutrition(NUTRITION_LEVEL_CURSED)
logmsg = "starvation."
if("Cluwne")
H.makeCluwne()
@@ -1963,37 +1963,39 @@
usr.client.create_eventmob_for(H, 1)
logmsg = "hunter."
if("Crew Traitor")
+ if(!H.mind)
+ to_chat(usr, "This mob has no mind!")
+ return
+
var/list/possible_traitors = list()
for(var/mob/living/player in GLOB.living_mob_list)
- if(player.client && player.mind && !player.mind.special_role && player.stat != DEAD && player != H)
- if(ishuman(player))
+ if(player.client && player.mind && player.stat != DEAD && player != H)
+ if(ishuman(player) && !player.mind.special_role)
if(player.client && (ROLE_TRAITOR in player.client.prefs.be_special) && !jobban_isbanned(player, ROLE_TRAITOR) && !jobban_isbanned(player, "Syndicate"))
possible_traitors += player.mind
+
for(var/datum/mind/player in possible_traitors)
if(player.current)
if(ismindshielded(player.current))
possible_traitors -= player
+
if(possible_traitors.len)
var/datum/mind/newtraitormind = pick(possible_traitors)
- var/mob/living/newtraitor = newtraitormind.current
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = newtraitormind
+ var/datum/objective/assassinate/kill_objective = new()
kill_objective.target = H.mind
- kill_objective.explanation_text = "Assassinate [H.real_name], the [H.mind.assigned_role]."
- newtraitormind.objectives += kill_objective
- SSticker.mode.equip_traitor(newtraitor)
- SSticker.mode.traitors |= newtraitor.mind
- to_chat(newtraitor, "ATTENTION: It is time to pay your debt to the Syndicate...")
- to_chat(newtraitor, "You are now a traitor.")
- to_chat(newtraitor, "Goal: KILL [H.real_name], currently in [get_area(H.loc)]");
- newtraitor.mind.special_role = SPECIAL_ROLE_TRAITOR
- var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_TRAITOR]
- tatorhud.join_hud(newtraitor)
- set_antag_hud(newtraitor, "hudsyndicate")
+ kill_objective.owner = newtraitormind
+ kill_objective.explanation_text = "Assassinate [H.mind], the [H.mind.assigned_role]"
+ var/datum/antagonist/traitor/T = new()
+ T.give_objectives = FALSE
+ T.add_objective(kill_objective)
+ to_chat(newtraitormind, "ATTENTION: It is time to pay your debt to the Syndicate...")
+ to_chat(newtraitormind, "Goal: KILL [H.real_name], currently in [get_area(H.loc)]")
+ newtraitormind.add_antag_datum(T)
else
to_chat(usr, "ERROR: Failed to create a traitor.")
return
logmsg = "crew traitor."
+
if("Floor Cluwne")
var/turf/T = get_turf(M)
var/mob/living/simple_animal/hostile/floor_cluwne/FC = new /mob/living/simple_animal/hostile/floor_cluwne(T)
@@ -2687,28 +2689,16 @@
return
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","TA([objective])")
+
for(var/mob/living/carbon/human/H in GLOB.player_list)
if(H.stat == 2 || !H.client || !H.mind) continue
if(is_special_character(H)) continue
//traitorize(H, objective, 0)
- SSticker.mode.traitors += H.mind
- H.mind.special_role = SPECIAL_ROLE_TRAITOR
- var/datum/objective/new_objective = new
- new_objective.owner = H
- new_objective.explanation_text = objective
- H.mind.objectives += new_objective
- SSticker.mode.greet_traitor(H.mind)
- //ticker.mode.forge_traitor_objectives(H.mind)
- SSticker.mode.finalize_traitor(H.mind)
+ H.mind.add_antag_datum(/datum/antagonist/traitor)
+
for(var/mob/living/silicon/A in GLOB.player_list)
- SSticker.mode.traitors += A.mind
- A.mind.special_role = SPECIAL_ROLE_TRAITOR
- var/datum/objective/new_objective = new
- new_objective.owner = A
- new_objective.explanation_text = objective
- A.mind.objectives += new_objective
- SSticker.mode.greet_traitor(A.mind)
- SSticker.mode.finalize_traitor(A.mind)
+ A.mind.add_antag_datum(/datum/antagonist/traitor)
+
message_admins("[key_name_admin(usr)] used everyone is a traitor secret. Objective is [objective]", 1)
log_admin("[key_name(usr)] used everyone is a traitor secret. Objective is [objective]")
@@ -2860,19 +2850,25 @@
if("guns")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","SG")
- usr.rightandwrong(FALSE)
+ var/survivor_probability = 0
+ switch(alert("Do you want this to create survivors antagonists?", , "No Antags", "Some Antags", "All Antags!"))
+ if("Some Antags")
+ survivor_probability = 25
+ if("All Antags!")
+ survivor_probability = 100
+
+ rightandwrong(SUMMON_GUNS, usr, survivor_probability)
if("magic")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","SM")
- usr.rightandwrong(TRUE)
- if("revolver")
- feedback_inc("admin_secrets_fun_used", 1)
- feedback_add_details("admin_secrets_fun_used", "SRD")
- usr.rightandwrong(FALSE, revolver_fight = TRUE)
- if("fakerevolver")
- feedback_inc("admin_secrets_fun_used", 1)
- feedback_add_details("admin_secrets_fun_used", "SFD")
- usr.rightandwrong(FALSE, fake_revolver_fight = TRUE)
+ var/survivor_probability = 0
+ switch(alert("Do you want this to create survivors antagonists?", , "No Antags", "Some Antags", "All Antags!"))
+ if("Some Antags")
+ survivor_probability = 25
+ if("All Antags!")
+ survivor_probability = 100
+
+ rightandwrong(SUMMON_MAGIC, usr, survivor_probability)
if("tdomereset")
var/delete_mobs = alert("Clear all mobs?","Confirm","Yes","No","Cancel")
if(delete_mobs == "Cancel")
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 11664349274..57f88d20351 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -95,6 +95,16 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
to_chat(usr, "[procname] returned: [!isnull(returnval) ? returnval : "null"]")
feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+GLOBAL_VAR(AdminProcCaller)
+GLOBAL_PROTECT(AdminProcCaller)
+
+/proc/IsAdminAdvancedProcCall()
+#ifdef TESTING
+ return FALSE
+#else
+ return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey
+#endif
+
/client/proc/callproc_datum(var/A as null|area|mob|obj|turf)
set category = "Debug"
set name = "Atom ProcCall"
diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm
index bdef649468d..4d60fb72bee 100644
--- a/code/modules/admin/verbs/freeze.dm
+++ b/code/modules/admin/verbs/freeze.dm
@@ -61,14 +61,12 @@ var/global/list/frozen_mob_list = list()
update_icons()
-/mob/living/carbon/slime/admin_Freeze(admin)
+/mob/living/simple_animal/slime/admin_Freeze(admin)
..(admin)
- adjustToxLoss(1010101010) //arbitrary large value
+ adjustHealth(1000) //arbitrary large value
-/mob/living/carbon/slime/admin_unFreeze(admin)
+/mob/living/simple_animal/slime/admin_unFreeze(admin)
..(admin)
- adjustToxLoss(-1010101010)
- stat = 0
revive()
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index aa22dfe944c..02e7dbd72cb 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -440,9 +440,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
//Now for special roles and equipment.
switch(new_character.mind.special_role)
if("traitor")
- SSjobs.AssignRank(new_character, new_character.mind.assigned_role, 0)
- SSjobs.EquipRank(new_character, new_character.mind.assigned_role, 1)
- SSticker.mode.equip_traitor(new_character)
+ if(new_character.mind.has_antag_datum(/datum/antagonist/traitor))
+ var/datum/antagonist/traitor/T = new_character.mind.has_antag_datum(/datum/antagonist/traitor)
+ T.equip_traitor(src)
+ else
+ new_character.mind.add_antag_datum(/datum/antagonist/traitor)
if("Wizard")
new_character.loc = pick(wizardstart)
//ticker.mode.learn_basic_spells(new_character)
@@ -462,13 +464,13 @@ Traitors and the like can also be revived with the previous role mostly intact.
if("Cyborg")//More rigging to make em' work and check if they're traitor.
new_character = new_character.Robotize()
if(new_character.mind.special_role=="traitor")
- call(/datum/game_mode/proc/add_law_zero)(new_character)
+ new_character.mind.add_antag_datum(/datum/antagonist/traitor)
if("AI")
new_character = new_character.AIize()
var/mob/living/silicon/ai/ai_character = new_character
ai_character.moveToAILandmark()
if(new_character.mind.special_role=="traitor")
- call(/datum/game_mode/proc/add_law_zero)(new_character)
+ new_character.mind.add_antag_datum(/datum/antagonist/traitor)
//Add aliens.
else
SSjobs.AssignRank(new_character, new_character.mind.assigned_role, 0)
diff --git a/code/modules/antagonists/survivalist/survivalist.dm b/code/modules/antagonists/survivalist/survivalist.dm
new file mode 100644
index 00000000000..7d08e18834c
--- /dev/null
+++ b/code/modules/antagonists/survivalist/survivalist.dm
@@ -0,0 +1,41 @@
+/datum/antagonist/survivalist
+ name = "Survivalist"
+ var/greet_message = ""
+
+/datum/antagonist/survivalist/proc/forge_objectives()
+ var/datum/objective/survive/survive = new
+ survive.owner = owner
+ objectives += survive
+ owner.objectives |= objectives
+
+/datum/antagonist/survivalist/on_gain()
+ owner.special_role = "survivalist"
+ forge_objectives()
+ . = ..()
+
+/datum/antagonist/survivalist/greet()
+ to_chat(owner.current, "You are the survivalist! [greet_message]")
+ owner.announce_objectives()
+
+/datum/antagonist/survivalist/guns
+ greet_message = "Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, by any means necessary. Kill anyone who gets in your way."
+
+/datum/antagonist/survivalist/guns/forge_objectives()
+ var/datum/objective/steal_five_of_type/summon_guns/guns = new
+ guns.owner = owner
+ objectives += guns
+ ..()
+
+/datum/antagonist/survivalist/magic
+ name = "Amateur Magician"
+ greet_message = "Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way."
+
+/datum/antagonist/survivalist/magic/greet()
+ ..()
+ to_chat(owner.current, "As a wonderful magician, you should remember that spellbooks don't mean anything if they are used up.")
+
+/datum/antagonist/survivalist/magic/forge_objectives()
+ var/datum/objective/steal_five_of_type/summon_magic/magic = new
+ magic.owner = owner
+ objectives += magic
+ ..()
\ No newline at end of file
diff --git a/code/modules/antagonists/traitor/datum_mindslave.dm b/code/modules/antagonists/traitor/datum_mindslave.dm
new file mode 100644
index 00000000000..ae728b95773
--- /dev/null
+++ b/code/modules/antagonists/traitor/datum_mindslave.dm
@@ -0,0 +1,52 @@
+
+// For Mindslaves and Zealots
+/datum/antagonist/mindslave
+ name = "Mindslave"
+ roundend_category = "mindslaves"
+ job_rank = ROLE_MINDSLAVE
+ var/special_role = ROLE_MINDSLAVE
+
+/datum/antagonist/mindslave/on_gain()
+ // Handling mindslave objectives on top of other antag objective sucks, so Im just gonna do it like this
+ to_chat(owner.current, "New Objective: [objectives[objectives.len].explanation_text]")
+ update_mindslave_icons_added()
+
+/datum/antagonist/mindslave/on_removal()
+ if(owner.som)
+ var/datum/mindslaves/slaved = owner.som
+ slaved.serv -= owner
+ slaved.leave_serv_hud(owner)
+ antag_memory = ""
+ owner.special_role = null
+ update_mindslave_icons_removed()
+ ..()
+
+/datum/antagonist/mindslave/apply_innate_effects()
+ . = ..()
+ if(owner.assigned_role == "Clown")
+ var/mob/living/carbon/human/slave_mob = owner.current
+ if(slave_mob && istype(slave_mob))
+ to_chat(slave_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
+ slave_mob.mutations.Remove(CLUMSY)
+
+/datum/antagonist/mindslave/remove_innate_effects()
+ . = ..()
+ if(owner.assigned_role == "Clown")
+ var/mob/living/carbon/human/slave_mob = owner.current
+ if(slave_mob && istype(slave_mob))
+ slave_mob.mutations.Add(CLUMSY)
+
+/datum/antagonist/mindslave/proc/add_objective(datum/objective/O)
+ objectives += O
+
+/datum/antagonist/mindslave/proc/remove_objective(datum/objective/O)
+ objectives -= O
+
+/datum/antagonist/mindslave/proc/update_mindslave_icons_added()
+ var/datum/atom_hud/antag/traitorhud = huds[ANTAG_HUD_TRAITOR]
+ traitorhud.join_hud(owner.current, null)
+ set_antag_hud(owner.current, "hudmindslave")
+
+/datum/antagonist/mindslave/proc/update_mindslave_icons_removed()
+ var/datum/atom_hud/antag/traitorhud = huds[ANTAG_HUD_TRAITOR]
+ traitorhud.leave_hud(owner.current, null)
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
new file mode 100644
index 00000000000..4e9a5ad4bf7
--- /dev/null
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -0,0 +1,418 @@
+#define TRAITOR_HUMAN "human"
+#define TRAITOR_AI "AI"
+
+// For "Actual traitors"
+/datum/antagonist/traitor
+ name = "Traitor"
+ roundend_category = "traitors"
+ job_rank = ROLE_TRAITOR
+ var/special_role = ROLE_TRAITOR
+ var/give_objectives = TRUE
+ var/should_give_codewords = TRUE
+ var/should_equip = TRUE
+ var/traitor_kind = TRAITOR_HUMAN
+ var/list/assigned_targets = list() // This includes assassinate as well as steal objectives. prevents duplicate objectives
+
+
+/datum/antagonist/traitor/on_gain()
+ if(owner.current && isAI(owner.current))
+ traitor_kind = TRAITOR_AI
+
+ var/datum/mindslaves/slaved = new()
+ slaved.masters += owner
+ owner.som = slaved //we MIGHT want to mindslave someone
+ SSticker.mode.traitors += owner
+ owner.special_role = special_role
+
+ if(give_objectives)
+ forge_traitor_objectives()
+ if(!silent)
+ greet()
+ update_traitor_icons_added()
+ finalize_traitor()
+
+
+/datum/antagonist/traitor/on_removal()
+ //Remove malf powers.
+ if(traitor_kind == TRAITOR_AI && owner.current && isAI(owner.current))
+ var/mob/living/silicon/ai/A = owner.current
+ A.clear_zeroth_law()
+ A.common_radio.channels.Remove("Syndicate") // De-traitored AIs can still state laws over the syndicate channel without this
+ A.laws.sorted_laws = A.laws.inherent_laws.Copy() // AI's 'notify laws' button will still state a law 0 because sorted_laws contains it
+ A.show_laws()
+ A.malf_picker.remove_malf_verbs(A)
+ A.verbs -= /mob/living/silicon/ai/proc/choose_modules
+ qdel(A.malf_picker)
+
+ if(owner.som)
+ var/datum/mindslaves/slaved = owner.som
+ slaved.masters -= owner
+ slaved.serv -= owner
+ owner.som = null
+ slaved.leave_serv_hud(owner)
+
+ assigned_targets.Cut()
+ SSticker.mode.traitors -= owner
+ owner.special_role = null
+ update_traitor_icons_removed()
+
+ if(!silent && owner.current)
+ antag_memory = ""
+ to_chat(owner.current," You are no longer a [special_role]! ")
+ ..()
+
+
+/datum/antagonist/traitor/apply_innate_effects()
+ . = ..()
+ if(owner.assigned_role == "Clown")
+ var/mob/living/carbon/human/traitor_mob = owner.current
+ if(traitor_mob && istype(traitor_mob))
+ to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
+ traitor_mob.mutations.Remove(CLUMSY)
+
+
+/datum/antagonist/traitor/remove_innate_effects()
+ . = ..()
+ if(owner.assigned_role == "Clown")
+ var/mob/living/carbon/human/traitor_mob = owner.current
+ if(traitor_mob && istype(traitor_mob))
+ traitor_mob.mutations.Add(CLUMSY)
+
+// Adding/removing objectives in the owner's mind until we can datumize all antags. Then we can use the /datum/antagonist/objectives var to handle them
+// Change "owner.objectives" to "objectives" once objectives are handled in antag datums instead of the mind
+/datum/antagonist/traitor/proc/add_objective(datum/objective/O)
+ owner.objectives += O
+
+/datum/antagonist/traitor/proc/remove_objective(datum/objective/O)
+ owner.objectives -= O
+
+
+/datum/antagonist/traitor/proc/forge_traitor_objectives()
+ switch(traitor_kind)
+ if(TRAITOR_AI)
+ forge_ai_objectives()
+ else
+ forge_human_objectives()
+
+
+/datum/antagonist/traitor/proc/forge_human_objectives()
+ var/is_hijacker = prob(10)
+ var/martyr_chance = prob(20)
+ var/objective_count = is_hijacker //Hijacking counts towards number of objectives
+ if(!SSticker.mode.exchange_blue && SSticker.mode.traitors.len >= 8) //Set up an exchange if there are enough traitors
+ if(!SSticker.mode.exchange_red)
+ SSticker.mode.exchange_red = owner
+ else
+ SSticker.mode.exchange_blue = owner
+ assign_exchange_role(SSticker.mode.exchange_red)
+ assign_exchange_role(SSticker.mode.exchange_blue)
+ objective_count += 1 //Exchange counts towards number of objectives
+
+
+ var/objective_amount = config.traitor_objectives_amount
+
+ if(is_hijacker && objective_count <= objective_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
+ if (!(locate(/datum/objective/hijack) in objectives))
+ var/datum/objective/hijack/hijack_objective = new
+ hijack_objective.owner = owner
+ add_objective(hijack_objective)
+ return
+
+ for(var/i = objective_count, i < objective_amount)
+ i += forge_single_objective()
+
+ var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead.
+ for(var/datum/objective/O in owner.objectives)
+ if(!O.martyr_compatible)
+ martyr_compatibility = 0
+ break
+
+ if(martyr_compatibility && martyr_chance)
+ var/datum/objective/die/martyr_objective = new
+ martyr_objective.owner = owner
+ add_objective(martyr_objective)
+ return
+
+ if(!(locate(/datum/objective/escape) in objectives))
+ var/datum/objective/escape/escape_objective = new
+ escape_objective.owner = owner
+ add_objective(escape_objective)
+ return
+
+
+/datum/antagonist/traitor/proc/forge_ai_objectives()
+ var/objective_count = 0
+ var/try_again = TRUE
+
+ if(prob(30))
+ objective_count += forge_single_objective()
+
+ for(var/i = objective_count, i < config.traitor_objectives_amount)
+ var/datum/objective/assassinate/kill_objective = new
+ kill_objective.owner = owner
+ kill_objective.find_target()
+ if("[kill_objective.target]" in assigned_targets) // In the rare case the game can't find a target for the AI thats not a duplicate
+ if(try_again) // It will attempt to location another target ONCE
+ try_again = FALSE // This code will really only come into play on lowpop rounds where getting duplicate targets is more common
+ continue
+ assigned_targets.Add("[kill_objective.target]")
+ add_objective(kill_objective)
+ i += 1
+ var/datum/objective/survive/survive_objective = new
+ survive_objective.owner = owner
+ add_objective(survive_objective)
+
+
+/datum/antagonist/traitor/proc/forge_single_objective()
+ switch(traitor_kind)
+ if(TRAITOR_AI)
+ return forge_single_AI_objective()
+ else
+ return forge_single_human_objective()
+
+
+/datum/antagonist/traitor/proc/forge_single_human_objective() // Returns how many objectives are added
+ . = 1
+ if(prob(50))
+ var/list/active_ais = active_ais()
+ if(active_ais.len && prob(100/GLOB.player_list.len))
+ var/datum/objective/destroy/destroy_objective = new
+ destroy_objective.owner = owner
+ destroy_objective.find_target()
+ if("[destroy_objective]" in assigned_targets) // Is this target already in their list of assigned targets? If so, don't add this objective and return
+ return 0
+ else if(destroy_objective.target) // Is the target a real one and not null? If so, add it to our list of targets to avoid duplicate targets
+ assigned_targets.Add("[destroy_objective.target]") // This logic is applied to all traitor objectives including steal objectives
+ add_objective(destroy_objective)
+
+ else if(prob(5))
+ var/datum/objective/debrain/debrain_objective = new
+ debrain_objective.owner = owner
+ debrain_objective.find_target()
+ if("[debrain_objective]" in assigned_targets)
+ return 0
+ else if(debrain_objective.target)
+ assigned_targets.Add("[debrain_objective.target]")
+ add_objective(debrain_objective)
+
+ else if(prob(30))
+ var/datum/objective/maroon/maroon_objective = new
+ maroon_objective.owner = owner
+ maroon_objective.find_target()
+ if("[maroon_objective]" in assigned_targets)
+ return 0
+ else if(maroon_objective.target)
+ assigned_targets.Add("[maroon_objective.target]")
+ add_objective(maroon_objective)
+
+ else
+ var/datum/objective/assassinate/kill_objective = new
+ kill_objective.owner = owner
+ kill_objective.find_target()
+ if("[kill_objective.target]" in assigned_targets)
+ return 0
+ else if(kill_objective.target)
+ assigned_targets.Add("[kill_objective.target]")
+ add_objective(kill_objective)
+
+ else
+ var/datum/objective/steal/steal_objective = new
+ steal_objective.owner = owner
+ steal_objective.find_target()
+ if("[steal_objective.steal_target]" in assigned_targets)
+ return 0
+ else if(steal_objective.steal_target)
+ assigned_targets.Add("[steal_objective.steal_target]")
+ add_objective(steal_objective)
+
+
+/datum/antagonist/traitor/proc/forge_single_AI_objective()
+ . = 1
+ var/special_pick = rand(1,2)
+ switch(special_pick)
+ if(1) // AI hijack
+ var/datum/objective/block/block_objective = new
+ block_objective.owner = owner
+ add_objective(block_objective)
+ if(2) // Protect and strand a target
+ var/datum/objective/protect/yandere_one = new
+ yandere_one.owner = owner
+ yandere_one.find_target()
+
+ if("[yandere_one.target]" in assigned_targets)
+ return 0
+ else if(yandere_one.target)
+ assigned_targets.Add("[yandere_one.target]")
+
+ add_objective(yandere_one)
+ var/datum/objective/maroon/yandere_two = new
+ yandere_two.owner = owner
+ yandere_two.target = yandere_one.target
+ yandere_two.explanation_text = "Prevent [yandere_one.target], the [yandere_one.target.assigned_role] from escaping alive."
+ add_objective(yandere_two)
+
+
+/datum/antagonist/traitor/greet()
+ to_chat(owner.current, "You are a [owner.special_role]!")
+ if(!LAZYLEN(owner.objectives)) // Remove "owner" when objectives are handled in the datum
+ to_chat(owner.current, "You don't have any objectives right now.")
+ else
+ owner.announce_objectives()
+ if(should_give_codewords)
+ give_codewords()
+
+
+/datum/antagonist/traitor/proc/update_traitor_icons_added(datum/mind/traitor_mind)
+ var/datum/atom_hud/antag/traitorhud = huds[ANTAG_HUD_TRAITOR]
+ traitorhud.join_hud(owner.current, null)
+ set_antag_hud(owner.current, "hudsyndicate")
+
+
+/datum/antagonist/traitor/proc/update_traitor_icons_removed(datum/mind/traitor_mind)
+ var/datum/atom_hud/antag/traitorhud = huds[ANTAG_HUD_TRAITOR]
+ traitorhud.leave_hud(owner.current, null)
+ set_antag_hud(owner.current, null)
+
+
+/datum/antagonist/traitor/proc/finalize_traitor()
+ switch(traitor_kind)
+ if(TRAITOR_AI)
+ add_law_zero()
+ owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
+ var/mob/living/silicon/ai/A = owner.current
+ A.show_laws()
+ if(TRAITOR_HUMAN)
+ if(should_equip)
+ equip_traitor()
+ owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
+
+
+/datum/antagonist/traitor/proc/give_codewords()
+ if(!owner.current)
+ return
+ var/mob/traitor_mob = owner.current
+
+ var/phrases = jointext(GLOB.syndicate_code_phrase, ", ")
+ var/responses = jointext(GLOB.syndicate_code_response, ", ")
+
+ to_chat(traitor_mob, "The Syndicate have provided you with the following codewords to identify fellow agents:")
+ to_chat(traitor_mob, "Code Phrase: [phrases]")
+ to_chat(traitor_mob, "Code Response: [responses]")
+
+ antag_memory += "Code Phrase: [phrases]
"
+ antag_memory += "Code Response: [responses]
"
+
+ to_chat(traitor_mob, "Use the codewords during regular conversation to identify other agents. Proceed with caution, however, as everyone is a potential foe.")
+
+
+/datum/antagonist/traitor/proc/add_law_zero()
+ var/mob/living/silicon/ai/killer = owner.current
+ if(!killer || !istype(killer))
+ return
+ var/law = "Accomplish your objectives at all costs."
+ var/law_borg = "Accomplish your AI's objectives at all costs."
+ killer.set_zeroth_law(law, law_borg)
+ killer.set_syndie_radio()
+ to_chat(killer, "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!")
+ killer.add_malf_picker()
+
+
+/datum/antagonist/traitor/proc/equip_traitor()
+
+ if(traitor_kind == TRAITOR_HUMAN)
+ var/mob/living/carbon/human/traitor_mob = owner.current
+
+ // find a radio! toolbox(es), backpack, belt, headset
+ var/obj/item/R = locate(/obj/item/pda) in traitor_mob.contents //Hide the uplink in a PDA if available, otherwise radio
+ if(!R)
+ R = locate(/obj/item/radio) in traitor_mob.contents
+
+ if(!R)
+ to_chat(traitor_mob, "Unfortunately, the Syndicate wasn't able to get you a radio.")
+ . = 0
+ else
+ if(istype(R, /obj/item/radio))
+ // generate list of radio freqs
+ var/obj/item/radio/target_radio = R
+ var/freq = PUBLIC_LOW_FREQ
+ var/list/freqlist = list()
+ while(freq <= PUBLIC_HIGH_FREQ)
+ if(freq < 1451 || freq > 1459)
+ freqlist += freq
+ freq += 2
+ if((freq % 2) == 0)
+ freq += 1
+ freq = freqlist[rand(1, freqlist.len)]
+
+ var/obj/item/uplink/hidden/T = new(R)
+ target_radio.hidden_uplink = T
+ T.uplink_owner = "[traitor_mob.key]"
+ target_radio.traitor_frequency = freq
+ to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features.")
+ traitor_mob.mind.store_memory("Radio Freq: [format_frequency(freq)] ([R.name]).")
+ else if(istype(R, /obj/item/pda))
+ // generate a passcode if the uplink is hidden in a PDA
+ var/pda_pass = "[rand(100,999)] [pick("Alpha","Bravo","Delta","Omega")]"
+
+ var/obj/item/uplink/hidden/T = new(R)
+ R.hidden_uplink = T
+ T.uplink_owner = "[traitor_mob.key]"
+ var/obj/item/pda/P = R
+ P.lock_code = pda_pass
+
+ to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [R.name]. Simply enter the code \"[pda_pass]\" into the ringtone select to unlock its hidden features.")
+ antag_memory += ("Uplink Passcode: [pda_pass] ([R.name].")
+ return 1
+
+
+/datum/antagonist/traitor/proc/assign_exchange_role(var/datum/mind/owner)
+ //set faction
+ var/faction = "red"
+ if(owner == SSticker.mode.exchange_blue)
+ faction = "blue"
+
+ //Assign objectives
+ var/datum/objective/steal/exchange/exchange_objective = new
+ exchange_objective.set_faction(faction,((faction == "red") ? SSticker.mode.exchange_blue : SSticker.mode.exchange_red))
+ exchange_objective.owner = owner
+ owner.objectives += exchange_objective
+
+ if(prob(20))
+ var/datum/objective/steal/exchange/backstab/backstab_objective = new
+ backstab_objective.set_faction(faction)
+ backstab_objective.owner = owner
+ owner.objectives += backstab_objective
+
+ //Spawn and equip documents
+ var/mob/living/carbon/human/mob = owner.current
+
+ var/obj/item/folder/syndicate/folder
+ if(owner == SSticker.mode.exchange_red)
+ folder = new/obj/item/folder/syndicate/red(mob.locs)
+ else
+ folder = new/obj/item/folder/syndicate/blue(mob.locs)
+
+ var/list/slots = list (
+ "backpack" = slot_in_backpack,
+ "left pocket" = slot_l_store,
+ "right pocket" = slot_r_store,
+ "left hand" = slot_l_hand,
+ "right hand" = slot_r_hand,
+ )
+
+ var/where = "At your feet"
+ var/equipped_slot = mob.equip_in_one_of_slots(folder, slots)
+ if(equipped_slot)
+ where = "In your [equipped_slot]"
+ to_chat(mob, "
[where] is a folder containing secret documents that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile.
")
+ mob.update_icons()
+
+
+/datum/antagonist/traitor/roundend_report_footer()
+ var/phrases = jointext(GLOB.syndicate_code_phrase, ", ")
+ var/responses = jointext(GLOB.syndicate_code_response, ", ")
+
+ var message = "
The code phrases were: [phrases]
\
+ The code responses were: [responses]
"
+
+ return message
diff --git a/code/modules/arcade/arcade_base.dm b/code/modules/arcade/arcade_base.dm
index c3158e9ccba..38c034927bc 100644
--- a/code/modules/arcade/arcade_base.dm
+++ b/code/modules/arcade/arcade_base.dm
@@ -22,18 +22,18 @@
qdel(src)
/obj/machinery/arcade/examine(mob/user)
- ..(user)
+ . = ..()
if(freeplay)
- to_chat(user, "Someone enabled freeplay on this machine!")
+ . += "Someone enabled freeplay on this machine!"
else
if(token_price)
- to_chat(user, "\The [src.name] costs [token_price] credits per play.")
+ . += "\The [src.name] costs [token_price] credits per play."
if(!tokens)
- to_chat(user, "\The [src.name] has no available play credits. Better feed the machine!")
+ . += "\The [src.name] has no available play credits. Better feed the machine!"
else if(tokens == 1)
- to_chat(user, "\The [src.name] has only 1 play credit left!")
+ . += "\The [src.name] has only 1 play credit left!"
else
- to_chat(user, "\The [src.name] has [tokens] play credits!")
+ . += "\The [src.name] has [tokens] play credits!"
/obj/machinery/arcade/attack_hand(mob/user as mob)
if(..())
diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm
index 5e0b463af30..d8ee727f2f8 100644
--- a/code/modules/assembly/assembly.dm
+++ b/code/modules/assembly/assembly.dm
@@ -128,12 +128,12 @@
STOP_PROCESSING(SSobj, src)
/obj/item/assembly/examine(mob/user)
- ..()
+ . = ..()
if(in_range(src, user) || loc == user)
if(secured)
- to_chat(user, "[src] is ready!")
+ . += "[src] is ready!"
else
- to_chat(user, "[src] can be attached!")
+ . += "[src] can be attached!"
/obj/item/assembly/attack_self(mob/user)
if(!user)
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index 058dd4cd0f2..e0454d5f5ea 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -13,8 +13,8 @@
origin_tech = "materials=1;engineering=1"
/obj/item/onetankbomb/examine(mob/user)
- ..(user)
- user.examinate(bombtank)
+ . = ..()
+ . += bombtank.examine(user)
/obj/item/onetankbomb/update_icon()
if(bombtank)
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index d19682d1eb9..ac4613575e8 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -70,12 +70,12 @@
/obj/item/assembly_holder/examine(mob/user)
- ..(user)
+ . = ..()
if(in_range(src, user) || loc == user)
if(secured)
- to_chat(user, "[src] is ready!")
+ . += "[src] is ready!"
else
- to_chat(user, "[src] can be attached!")
+ . += "[src] can be attached!"
/obj/item/assembly_holder/HasProximity(atom/movable/AM)
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 37f5916d535..b9d3ee2afc1 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -29,8 +29,8 @@
return "The assembly is [secured ? "secure" : "not secure"]. The infrared trigger is [on ? "on" : "off"]."
/obj/item/assembly/infra/examine(mob/user)
- ..()
- to_chat(user, describe())
+ . = ..()
+ . += describe()
/obj/item/assembly/infra/activate()
if(!..())
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index 3bb83857dd9..f4869f10d33 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -9,9 +9,9 @@
bomb_name = "contact mine"
/obj/item/assembly/mousetrap/examine(mob/user)
- ..(user)
+ . = ..()
if(armed)
- to_chat(user, "It looks like it's armed.")
+ . += "It looks like it's armed."
/obj/item/assembly/mousetrap/activate()
if(..())
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index 3598a1469b7..7131b79b03b 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -48,13 +48,14 @@
if(!O.can_reenter_corpse)
to_chat(user, "You have forfeited the right to respawn.")
return
- if(QDELETED(src) || QDELETED(user))
- return
var/ghost_role = alert("Become [mob_name]? (Warning, You can no longer be cloned!)",,"Yes","No")
- if(ghost_role == "No" || !loc)
+ if(ghost_role == "No")
return
if(!species_prompt())
return
+ if(!loc || !uses || QDELETED(src) || QDELETED(user))
+ to_chat(user, "The [name] is no longer usable!")
+ return
log_game("[user.ckey] became [mob_name]")
create(ckey = user.ckey)
diff --git a/code/modules/awaymissions/mission_code/spacehotel.dm b/code/modules/awaymissions/mission_code/spacehotel.dm
index d2fda046d7e..e9c74d73ea9 100644
--- a/code/modules/awaymissions/mission_code/spacehotel.dm
+++ b/code/modules/awaymissions/mission_code/spacehotel.dm
@@ -121,8 +121,8 @@
return ..()
/obj/machinery/door/unpowered/hotel_door/examine(mob/user)
- ..()
- to_chat(user, "This room is currently [occupant ? "" : "un"]occupied.")
+ . = ..()
+ . += "This room is currently [occupant ? "" : "un"]occupied."
/obj/machinery/door/unpowered/hotel_door/allowed(mob/living/carbon/user)
for(var/obj/item/card/hotel_card/C in user.get_all_slots())
diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm
index c1ad8d6d103..d5e4b2bf3fe 100644
--- a/code/modules/client/preference/preferences_toggles.dm
+++ b/code/modules/client/preference/preferences_toggles.dm
@@ -287,3 +287,10 @@
to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTPDA) ? "see all PDA messages" : "no longer see PDA messages"].")
prefs.save_preferences(src)
feedback_add_details("admin_verb","TGP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/verb/silence_current_midi()
+ set name = "Silence Current Midi"
+ set category = "Preferences"
+ set desc = "Silence the current admin midi playing"
+ usr.stop_sound_channel(CHANNEL_ADMIN)
+ to_chat(src, "The current admin midi has been silenced")
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 051b03d2252..b36dbc0bff9 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -579,6 +579,9 @@ BLIND // can't see anything
else
..() //This is required in order to ensure that the UI buttons for items that have alternate functions tied to UI buttons still work.
+/obj/item/clothing/suit/proc/special_overlays() // Does it have special overlays when worn?
+ return FALSE
+
//Spacesuit
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
// Meaning the the suit is defined directly after the corrisponding helmet. Just like below!
@@ -707,19 +710,19 @@ BLIND // can't see anything
return FALSE
/obj/item/clothing/under/examine(mob/user)
- ..(user)
- switch(src.sensor_mode)
+ . = ..()
+ switch(sensor_mode)
if(0)
- to_chat(user, "Its sensors appear to be disabled.")
+ . += "Its sensors appear to be disabled."
if(1)
- to_chat(user, "Its binary life sensors appear to be enabled.")
+ . += "Its binary life sensors appear to be enabled."
if(2)
- to_chat(user, "Its vital tracker appears to be enabled.")
+ . += "Its vital tracker appears to be enabled."
if(3)
- to_chat(user, "Its vital tracker and tracking beacon appear to be enabled.")
+ . += "Its vital tracker and tracking beacon appear to be enabled."
if(accessories.len)
for(var/obj/item/clothing/accessory/A in accessories)
- to_chat(user, "\A [A] is attached to it.")
+ . += "\A [A] is attached to it."
/obj/item/clothing/under/verb/rollsuit()
diff --git a/code/modules/clothing/gloves/rings.dm b/code/modules/clothing/gloves/rings.dm
index 9a512ca2cd5..6bef80bfe6d 100644
--- a/code/modules/clothing/gloves/rings.dm
+++ b/code/modules/clothing/gloves/rings.dm
@@ -21,11 +21,11 @@
icon_state = initial(icon_state)
/obj/item/clothing/gloves/ring/examine(mob/user)
- ..(user)
+ . = ..()
if(!fluff_material)
- to_chat(user, "This one is made of [material].")
+ . += "This one is made of [material]."
if(stud)
- to_chat(user, "It is adorned with a single gem.")
+ . += "It is adorned with a single gem."
/obj/item/clothing/gloves/ring/attackby(obj/item/I as obj, mob/user as mob, params)
if(istype(I, /obj/item/stack/sheet/mineral/diamond))
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index 97045483e99..7b0baef536f 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -33,8 +33,8 @@
return flags & NOSLIP
/obj/item/clothing/shoes/magboots/examine(mob/user)
- ..(user)
- to_chat(user, "Its [magpulse_name] appears to be [magpulse ? "enabled" : "disabled"].")
+ . = ..()
+ . += "Its [magpulse_name] appears to be [magpulse ? "enabled" : "disabled"]."
/obj/item/clothing/shoes/magboots/advance
diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm
index e5ed4ff94a3..0412570a161 100644
--- a/code/modules/clothing/spacesuits/alien.dm
+++ b/code/modules/clothing/spacesuits/alien.dm
@@ -233,6 +233,6 @@
flags &= ~NODROP
/obj/item/clothing/shoes/magboots/vox/examine(mob/user)
- ..(user)
+ . = ..()
if(magpulse)
- to_chat(user, "It would be hard to take these off without relaxing your grip first.")//theoretically this message should only be seen by the wearer when the claws are equipped.
+ . += "It would be hard to take these off without relaxing your grip first."//theoretically this message should only be seen by the wearer when the claws are equipped.
diff --git a/code/modules/clothing/spacesuits/breaches.dm b/code/modules/clothing/spacesuits/breaches.dm
index d47f06b125b..c8891fde00d 100644
--- a/code/modules/clothing/spacesuits/breaches.dm
+++ b/code/modules/clothing/spacesuits/breaches.dm
@@ -215,7 +215,7 @@ var/global/list/breach_burn_descriptors = list(
..()
/obj/item/clothing/suit/space/examine(mob/user)
- ..(user)
+ . = ..()
if(can_breach && breaches && breaches.len)
for(var/datum/breach/B in breaches)
- to_chat(user, "It has \a [B.descriptor].")
+ . += "It has \a [B.descriptor]."
diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm
index 861d8e8a433..4670eca24a8 100644
--- a/code/modules/clothing/spacesuits/ert.dm
+++ b/code/modules/clothing/spacesuits/ert.dm
@@ -27,8 +27,9 @@
to_chat(user, "User scanned as [camera.c_tag]. Camera activated.")
/obj/item/clothing/head/helmet/space/hardsuit/ert/examine(mob/user)
- if(..(user, 1) && has_camera)
- to_chat(user, "This helmet has a built-in camera. It's [camera ? "" : "in"]active.")
+ . = ..()
+ if(in_range(user, src) && has_camera)
+ . += "This helmet has a built-in camera. It's [camera ? "" : "in"]active."
/obj/item/clothing/suit/space/hardsuit/ert
name = "emergency response team suit"
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index d1554f84866..2a31c978996 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -409,33 +409,6 @@
/obj/item/clothing/head/helmet/space/hardsuit/syndi/freedom/update_icon()
return
-//Wizard hardsuit
-/obj/item/clothing/head/helmet/space/hardsuit/wizard
- name = "gem-encrusted hardsuit helmet"
- desc = "A bizarre gem-encrusted helmet that radiates magical energies."
- icon_state = "hardsuit0-wiz"
- item_state = "wiz_helm"
- item_color = "wiz"
- resistance_flags = FIRE_PROOF | ACID_PROOF //No longer shall our kind be foiled by lone chemists with spray bottles!
- armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100)
- heat_protection = HEAD //Uncomment to enable firesuit protection
- max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
- magical = TRUE
-
-/obj/item/clothing/suit/space/hardsuit/wizard
- icon_state = "hardsuit-wiz"
- name = "gem-encrusted hardsuit"
- desc = "A bizarre gem-encrusted suit that radiates magical energies."
- item_state = "wiz_hardsuit"
- w_class = WEIGHT_CLASS_NORMAL
- resistance_flags = FIRE_PROOF | ACID_PROOF
- armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100)
- allowed = list(/obj/item/teleportation_scroll,/obj/item/tank)
- heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection
- max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
- helmettype = /obj/item/clothing/head/helmet/space/hardsuit/wizard
- magical = TRUE
-
//Medical hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/medical
name = "medical hardsuit helmet"
@@ -530,23 +503,24 @@
var/recharge_rate = 1 //How quickly the shield recharges once it starts charging
var/shield_state = "shield-old"
var/shield_on = "shield-old"
- sprite_sheets = null
/obj/item/clothing/suit/space/hardsuit/shielded/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ recharge_cooldown = world.time + recharge_delay
if(current_charges > 0)
do_sparks(2, 1, src)
owner.visible_message("[owner]'s shields deflect [attack_text] in a shower of sparks!")
current_charges--
- recharge_cooldown = world.time + recharge_delay
- START_PROCESSING(SSobj, src)
+ if(recharge_rate)
+ START_PROCESSING(SSobj, src)
if(current_charges <= 0)
- owner.visible_message("[owner]'s shield overloads!")
+ owner.visible_message("[owner]'s shield overloads!")
shield_state = "broken"
owner.update_inv_wear_suit()
return 1
return 0
+
/obj/item/clothing/suit/space/hardsuit/shielded/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
@@ -554,18 +528,22 @@
/obj/item/clothing/suit/space/hardsuit/shielded/process()
if(world.time > recharge_cooldown && current_charges < max_charges)
current_charges = Clamp((current_charges + recharge_rate), 0, max_charges)
- playsound(loc, 'sound/magic/charge.ogg', 50, 1)
+ playsound(loc, 'sound/magic/charge.ogg', 50, TRUE)
if(current_charges == max_charges)
- playsound(loc, 'sound/machines/ding.ogg', 50, 1)
+ playsound(loc, 'sound/machines/ding.ogg', 50, TRUE)
STOP_PROCESSING(SSobj, src)
shield_state = "[shield_on]"
- if(istype(loc, /mob/living/carbon/human))
+ if(ishuman(loc))
var/mob/living/carbon/human/C = loc
C.update_inv_wear_suit()
+/obj/item/clothing/suit/space/hardsuit/shielded/special_overlays()
+ return mutable_appearance('icons/effects/effects.dmi', shield_state, MOB_LAYER + 0.01)
+
/obj/item/clothing/head/helmet/space/hardsuit/shielded
resistance_flags = FIRE_PROOF | ACID_PROOF
+
//////Syndicate Version
/obj/item/clothing/suit/space/hardsuit/shielded/syndi
@@ -579,14 +557,25 @@
slowdown = 0
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi
jetpack = /obj/item/tank/jetpack/suit
- sprite_sheets = list(
- "Unathi" = 'icons/mob/species/unathi/suit.dmi',
- "Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
- "Skrell" = 'icons/mob/species/skrell/suit.dmi',
- "Vox" = 'icons/mob/species/vox/suit.dmi',
- "Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi',
- "Drask" = 'icons/mob/species/drask/suit.dmi'
- )
+
+/obj/item/clothing/suit/space/hardsuit/shielded/syndi/attackby(obj/item/I, mob/user, params)
+ if(ismultitool(I))
+ if(shield_state == "broken")
+ to_chat(user, "You can't interface with the hardsuit's software if the shield's broken!")
+ return
+
+ if(shield_state == "shield-red")
+ shield_state = "shield-old"
+ shield_on = "shield-old"
+ to_chat(user, "You roll back the hardsuit's software, changing the shield's color!")
+
+ else
+ shield_state = "shield-red"
+ shield_on = "shield-red"
+ to_chat(user, "You update the hardsuit's hardware, changing back the shield's color to red.")
+ user.update_inv_wear_suit()
+ return
+ return ..()
/obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi
name = "blood-red hardsuit helmet"
diff --git a/code/modules/clothing/spacesuits/rig/modules/modules.dm b/code/modules/clothing/spacesuits/rig/modules/modules.dm
index 12df59f70d7..19c10a31c58 100644
--- a/code/modules/clothing/spacesuits/rig/modules/modules.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/modules.dm
@@ -55,15 +55,15 @@
var/list/stat_rig_module/stat_modules = new()
-/obj/item/rig_module/examine()
- ..()
+/obj/item/rig_module/examine(mob/user)
+ . = ..()
switch(damage)
if(0)
- to_chat(usr, "It is undamaged.")
+ . += "It is undamaged."
if(1)
- to_chat(usr, "It is badly damaged.")
+ . += "It is badly damaged."
if(2)
- to_chat(usr, "It is almost completely destroyed.")
+ . += "It is almost completely destroyed."
/obj/item/rig_module/attackby(obj/item/W as obj, mob/user as mob)
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index 36283c66bd7..c8b5e79eb32 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -83,18 +83,18 @@
var/datum/wires/rig/wires
var/datum/effect_system/spark_spread/spark_system
-/obj/item/rig/examine()
- to_chat(usr, "This is [bicon(src)][src.name].")
- to_chat(usr, "[src.desc]")
+/obj/item/rig/examine(mob/user)
+ . = list("This is [src].")
+ . += "[desc]"
if(wearer)
for(var/obj/item/piece in list(helmet,gloves,chest,boots))
if(!piece || piece.loc != wearer)
continue
- to_chat(usr, "[bicon(piece)] \The [piece] [piece.gender == PLURAL ? "are" : "is"] deployed.")
+ . += "[bicon(piece)] \The [piece] [piece.gender == PLURAL ? "are" : "is"] deployed."
- if(src.loc == usr)
- to_chat(usr, "The maintenance panel is [open ? "open" : "closed"].")
- to_chat(usr, "Hardsuit systems are [offline ? "offline" : "online"].")
+ if(loc == usr)
+ . += "The maintenance panel is [open ? "open" : "closed"]."
+ . += "Hardsuit systems are [offline ? "offline" : "online"]."
/obj/item/rig/get_cell()
return cell
diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm
index f1c709869b9..f623ba4c087 100644
--- a/code/modules/clothing/suits/wiz_robe.dm
+++ b/code/modules/clothing/suits/wiz_robe.dm
@@ -150,4 +150,55 @@
permeability_coefficient = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
resistance_flags = FLAMMABLE
- magical = FALSE
\ No newline at end of file
+ magical = FALSE
+
+//Shielded Armour
+
+/obj/item/clothing/suit/space/hardsuit/shielded/wizard
+ name = "battlemage armour"
+ desc = "Not all wizards are afraid of getting up close and personal."
+ icon_state = "hardsuit-wiz"
+ item_state = "wiz_hardsuit"
+ recharge_rate = 0
+ current_charges = 15
+ recharge_cooldown = INFINITY
+ shield_state = "shield-red"
+ shield_on = "shield-red"
+ min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT
+ max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/wizard
+ armor = list(melee = 30, bullet = 20, laser = 20, energy = 20, bomb = 20, bio = 20, rad = 20, fire = 100, acid = 100)
+ slowdown = 0
+ resistance_flags = FIRE_PROOF | ACID_PROOF
+ magical = TRUE
+
+/obj/item/clothing/head/helmet/space/hardsuit/shielded/wizard
+ name = "battlemage helmet"
+ desc = "A suitably impressive helmet."
+ icon_state = "hardsuit0-wiz"
+ item_state = "wiz_helm"
+ item_color = "wiz"
+ min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT
+ max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT
+ armor = list(melee = 30, bullet = 20, laser = 20, energy = 20, bomb = 20, bio = 20, rad = 20, fire = 100, acid = 100)
+ actions_types = null //No inbuilt light
+ resistance_flags = FIRE_PROOF | ACID_PROOF
+ magical = TRUE
+
+/obj/item/clothing/head/helmet/space/hardsuit/shielded/wizard/attack_self(mob/user)
+ return
+
+/obj/item/wizard_armour_charge
+ name = "battlemage shield charges"
+ desc = "A powerful rune that will increase the number of hits a suit of battlemage armour can take before failing.."
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "electricity2"
+
+/obj/item/wizard_armour_charge/afterattack(obj/item/clothing/suit/space/hardsuit/shielded/wizard/W, mob/user)
+ . = ..()
+ if(!istype(W))
+ to_chat(user, "The rune can only be used on battlemage armour!")
+ return
+ W.current_charges += 8
+ to_chat(user, "You charge [W]. It can now absorb [W.current_charges] hits.")
+ qdel(src)
\ No newline at end of file
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index df25a97dffb..11b7919f0ae 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -666,9 +666,9 @@
return access_id ? access_id.GetAccess() : ..()
/obj/item/clothing/accessory/petcollar/examine(mob/user)
- ..()
+ . = ..()
if(access_id)
- to_chat(user, "There is [bicon(access_id)] \a [access_id] clipped onto it.")
+ . += "There is [bicon(access_id)] \a [access_id] clipped onto it."
/obj/item/clothing/accessory/petcollar/equipped(mob/living/simple_animal/user)
if(istype(user))
diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm
index 29b89e8418d..9da7223be0c 100644
--- a/code/modules/clothing/under/accessories/holster.dm
+++ b/code/modules/clothing/under/accessories/holster.dm
@@ -87,11 +87,11 @@
..()
/obj/item/clothing/accessory/holster/examine(mob/user)
- ..(user)
+ . = ..()
if(holstered)
- to_chat(user, "A [holstered] is holstered here.")
+ . += "A [holstered] is holstered here."
else
- to_chat(user, "It is empty.")
+ . += "It is empty."
/obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user as mob)
..()
diff --git a/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm b/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm
index c3a8b09e57a..937d5111830 100644
--- a/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm
+++ b/code/modules/clothing/under/jobs/plasmamen/_plasmamen.dm
@@ -15,8 +15,8 @@
item_color = "plasmaman"
/obj/item/clothing/under/plasmaman/examine(mob/user)
- ..()
- to_chat(user, "There are [extinguishes_left] extinguisher charges left in this suit.")
+ . = ..()
+ . += "There are [extinguishes_left] extinguisher charges left in this suit."
/obj/item/clothing/under/plasmaman/proc/Extinguish(mob/living/carbon/human/H)
if(!istype(H))
diff --git a/code/modules/countdown/countdown.dm b/code/modules/countdown/countdown.dm
index 5710facad0b..b314acdcd41 100644
--- a/code/modules/countdown/countdown.dm
+++ b/code/modules/countdown/countdown.dm
@@ -20,7 +20,7 @@
/obj/effect/countdown/examine(mob/user)
. = ..()
- to_chat(user, "This countdown is displaying: [displayed_text]")
+ . += "This countdown is displaying: [displayed_text]"
/obj/effect/countdown/proc/attach(atom/A)
attached_to = A
diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index cbf11d23d99..d0ad4b8dc41 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -246,7 +246,7 @@
tools = list(/obj/item/screwdriver)
time = 100
category = CAT_WEAPONRY
- subcategory = CAT_AMMO
+ subcategory = CAT_WEAPON
/datum/crafting_recipe/chainsaw
name = "Chainsaw"
diff --git a/code/modules/events/anomaly_bluespace.dm b/code/modules/events/anomaly_bluespace.dm
index a8f11681577..c0d0472026f 100644
--- a/code/modules/events/anomaly_bluespace.dm
+++ b/code/modules/events/anomaly_bluespace.dm
@@ -43,9 +43,10 @@
var/y_distance = TO.y - FROM.y
var/x_distance = TO.x - FROM.x
for(var/atom/movable/A in range(12, FROM )) // iterate thru list of mobs in the area
- if(istype(A, /obj/item/radio/beacon)) continue // don't teleport beacons because that's just insanely stupid
- if(A.anchored) continue
-
+ if(istype(A, /obj/item/radio/beacon)) // don't teleport beacons because that's just insanely stupid
+ continue
+ if(A.anchored || A.move_resist == INFINITY)
+ continue
var/turf/newloc = locate(A.x + x_distance, A.y + y_distance, TO.z) // calculate the new place
if(!A.Move(newloc)) // if the atom, for some reason, can't move, FORCE them to move! :) We try Move() first to invoke any movement-related checks the atom needs to perform after moving
A.loc = locate(A.x + x_distance, A.y + y_distance, TO.z)
diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm
index 3c2e6025952..f281c549c97 100644
--- a/code/modules/events/anomaly_pyro.dm
+++ b/code/modules/events/anomaly_pyro.dm
@@ -22,7 +22,10 @@
if(newAnomaly.loc)
explosion(get_turf(newAnomaly), -1,0,3, flame_range = 4)
- var/mob/living/carbon/slime/S = new/mob/living/carbon/slime(get_turf(newAnomaly))
- S.colour = pick("red", "orange")
-
+ var/turf/T = get_turf(src)
+ var/new_colour = pick("red", "orange")
+ var/mob/living/simple_animal/slime/S = new(T, new_colour)
+ S.rabid = TRUE
+ S.amount_grown = SLIME_EVOLUTION_THRESHOLD
+ S.Evolve()
qdel(newAnomaly)
\ No newline at end of file
diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm
index 54394411e73..7a998f06dcb 100644
--- a/code/modules/events/blob.dm
+++ b/code/modules/events/blob.dm
@@ -1,6 +1,6 @@
/datum/event/blob
- announceWhen = 120
- endWhen = 180
+ announceWhen = 180
+ endWhen = 240
/datum/event/blob/announce()
event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index e53fda899e2..c02514d2a2a 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -423,7 +423,7 @@
color = "#ffffff"
/obj/structure/spacevine/examine(mob/user)
- ..()
+ . = ..()
var/text = "This one is a"
if(mutations.len)
for(var/A in mutations)
@@ -432,7 +432,7 @@
else
text += " normal"
text += " vine."
- to_chat(user, text)
+ . += text
/obj/structure/spacevine/proc/wither()
for(var/datum/spacevine_mutation/SM in mutations)
diff --git a/code/modules/fish/fishtank.dm b/code/modules/fish/fishtank.dm
index 9fb44aeba31..95cf9f15799 100644
--- a/code/modules/fish/fishtank.dm
+++ b/code/modules/fish/fishtank.dm
@@ -369,7 +369,7 @@
////////////////////////////// Feel free to try cleaning it up if you think of a better way to do it.
/obj/machinery/fishtank/examine(mob/user)
- ..(user)
+ . = ..()
var/examine_message = ""
//Approximate water level
@@ -474,8 +474,7 @@
//Finally, report the full examine_message constructed from the above reports
- to_chat(user, "[examine_message]")
- return examine_message
+ . += "[examine_message]"
//////////////////////////////
// ATACK PROCS //
diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm
index 83079a240f0..5b759b93d68 100644
--- a/code/modules/food_and_drinks/drinks/drinks.dm
+++ b/code/modules/food_and_drinks/drinks/drinks.dm
@@ -108,19 +108,19 @@
return FALSE
/obj/item/reagent_containers/food/drinks/examine(mob/user)
- if(!..(user, 1))
- return
- if(!reagents || reagents.total_volume == 0)
- to_chat(user, " \The [src] is empty!")
- else if(reagents.total_volume <= volume/4)
- to_chat(user, " \The [src] is almost empty!")
- else if(reagents.total_volume <= volume*0.66)
- to_chat(user, " \The [src] is half full!")// We're all optimistic, right?!
+ . = ..()
+ if(in_range(user, src))
+ if(!reagents || reagents.total_volume == 0)
+ . += " \The [src] is empty!"
+ else if(reagents.total_volume <= volume/4)
+ . += " \The [src] is almost empty!"
+ else if(reagents.total_volume <= volume*0.66)
+ . += " \The [src] is half full!"// We're all optimistic, right?!
- else if(reagents.total_volume <= volume*0.90)
- to_chat(user, " \The [src] is almost full!")
- else
- to_chat(user, " \The [src] is full!")
+ else if(reagents.total_volume <= volume*0.90)
+ . += " \The [src] is almost full!"
+ else
+ . += " \The [src] is full!"
////////////////////////////////////////////////////////////////////////////////
/// Drinks. END
diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm
index bebef085297..ef2ad5f777b 100644
--- a/code/modules/food_and_drinks/food/customizables.dm
+++ b/code/modules/food_and_drinks/food/customizables.dm
@@ -387,10 +387,10 @@
return ..()
/obj/item/reagent_containers/food/snacks/customizable/examine(mob/user)
- ..(user)
+ . = ..()
if(LAZYLEN(ingredients))
var/whatsinside = pick(ingredients)
- to_chat(user, " You think you can see [whatsinside] in there.")
+ . += " You think you can see [whatsinside] in there."
/obj/item/reagent_containers/food/snacks/customizable/proc/newname()
diff --git a/code/modules/food_and_drinks/food/foods/pasta.dm b/code/modules/food_and_drinks/food/foods/pasta.dm
index 41de9f4f565..5ba56146560 100644
--- a/code/modules/food_and_drinks/food/foods/pasta.dm
+++ b/code/modules/food_and_drinks/food/foods/pasta.dm
@@ -78,8 +78,9 @@
/obj/item/reagent_containers/food/snacks/lasagna
name = "Lasagna"
- icon_state = "lasagna"
desc = "Tajara love to eat this, for some reason."
+ icon = 'icons/obj/food/pasta.dmi'
+ icon_state = "lasagna"
filling_color = "#E18712"
list_reagents = list("nutriment" = 10, "msg" = 3, "vitamin" = 4, "tomatojuice" = 10)
tastes = list("pasta" = 1, "cheese" = 1, "tomato" = 1, "meat" = 1)
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index 672285b84d3..b2f0f5eb690 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -71,15 +71,15 @@
return
/obj/item/reagent_containers/food/snacks/examine(mob/user)
- if(..(user, 0))
- if(bitecount==0)
- return
- else if(bitecount==1)
- to_chat(user, "[src] was bitten by someone!")
- else if(bitecount<=3)
- to_chat(user, "[src] was bitten [bitecount] times!")
- else
- to_chat(user, "[src] was bitten multiple times!")
+ . = ..()
+ if(in_range(user, src))
+ if(bitecount > 0)
+ if(bitecount==1)
+ . += "[src] was bitten by someone!"
+ else if(bitecount<=3)
+ . += "[src] was bitten [bitecount] times!"
+ else
+ . += "[src] was bitten multiple times!"
/obj/item/reagent_containers/food/snacks/attackby(obj/item/W, mob/user, params)
@@ -180,7 +180,7 @@
/obj/item/reagent_containers/food/snacks/sliceable/examine(mob/user)
. = ..()
- to_chat(user, "Alt-click to put something small inside.")
+ . += "Alt-click to put something small inside."
/obj/item/reagent_containers/food/snacks/sliceable/AltClick(mob/user)
var/obj/item/I = user.get_active_hand()
diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
index 19c866fae43..394ee10384b 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
@@ -30,13 +30,10 @@
rating_speed = M.rating
/obj/machinery/processor/process()
- ..()
- // The irony
- // To be clear, if it's grinding, then it can't suck them up
if(processing)
return
- var/mob/living/carbon/slime/picked_slime
- for(var/mob/living/carbon/slime/slime in range(1, src))
+ var/mob/living/simple_animal/slime/picked_slime
+ for(var/mob/living/simple_animal/slime/slime in range(1, src))
if(slime.loc == src)
continue
if(slime.stat)
@@ -48,7 +45,7 @@
if(!P)
return
- visible_message("[picked_slime] is sucked into \the [src].")
+ visible_message("[picked_slime] is sucked into [src].")
picked_slime.forceMove(src)
//RECIPE DATUMS
@@ -110,18 +107,18 @@
/////MOB RECIPIES/////
//////////////////////
/datum/food_processor_process/mob/slime
- input = /mob/living/carbon/slime
+ input = /mob/living/simple_animal/slime
output = null
/datum/food_processor_process/mob/slime/process_food(loc, what, obj/machinery/processor/processor)
- var/mob/living/carbon/slime/S = what
+ var/mob/living/simple_animal/slime/S = what
var/C = S.cores
if(S.stat != DEAD)
- S.loc = loc
+ S.forceMove(processor.drop_location())
S.visible_message("[S] crawls free of the processor!")
return
for(var/i in 1 to (C+processor.rating_amount-1))
- new S.coretype(loc)
+ new S.coretype(processor.drop_location())
feedback_add_details("slime_core_harvested","[replacetext(S.colour," ","_")]")
..()
diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm
index 872bdc8e327..7be44052729 100644
--- a/code/modules/games/cards.dm
+++ b/code/modules/games/cards.dm
@@ -39,8 +39,8 @@
..()
/obj/item/deck/examine(mob/user)
- ..()
- to_chat(user,"It contains [cards.len ? cards.len : "no"] cards")
+ . = ..()
+ . +="It contains [cards.len ? cards.len : "no"] cards"
/obj/item/deck/attack_hand(mob/user as mob)
draw_card(user)
@@ -313,11 +313,11 @@
user.visible_message("[user] [concealed ? "conceals" : "reveals"] their hand.")
/obj/item/cardhand/examine(mob/user)
- ..(user)
+ . = ..()
if((!concealed) && cards.len)
- to_chat(user,"It contains:")
+ . +="It contains:"
for(var/datum/playingcard/P in cards)
- to_chat(user,"the [P.name].")
+ . +="the [P.name]."
// Datum action here
diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm
index 21ba7cb89e2..ef1a10cd85f 100644
--- a/code/modules/hydroponics/beekeeping/beebox.dm
+++ b/code/modules/hydroponics/beekeeping/beebox.dm
@@ -127,25 +127,25 @@
/obj/structure/beebox/examine(mob/user)
- ..()
+ . = ..()
if(!queen_bee)
- to_chat(user, "There is no queen bee! There won't bee any honeycomb without a queen!")
+ . += "There is no queen bee! There won't bee any honeycomb without a queen!"
var/half_bee = get_max_bees()*0.5
if(half_bee && (bees.len >= half_bee))
- to_chat(user, "This place is a BUZZ with activity... there are lots of bees!")
+ . += "This place is a BUZZ with activity... there are lots of bees!"
- to_chat(user, "[bee_resources]/100 resource supply.")
- to_chat(user, "[bee_resources]% towards a new honeycomb.")
- to_chat(user, "[bee_resources*2]% towards a new bee.")
+ . += "[bee_resources]/100 resource supply."
+ . += "[bee_resources]% towards a new honeycomb."
+ . += "[bee_resources*2]% towards a new bee."
if(honeycombs.len)
var/plural = honeycombs.len > 1
- to_chat(user, "There [plural? "are" : "is"] [honeycombs.len] uncollected honeycomb[plural ? "s":""] in the apiary.")
+ . += "There [plural? "are" : "is"] [honeycombs.len] uncollected honeycomb[plural ? "s":""] in the apiary."
if(honeycombs.len >= get_max_honeycomb())
- to_chat(user, "there's no room for more honeycomb!")
+ . += "there's no room for more honeycomb!"
/obj/structure/beebox/attackby(obj/item/I, mob/user, params)
diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm
index e701406897c..f194c48e019 100644
--- a/code/modules/hydroponics/fermenting_barrel.dm
+++ b/code/modules/hydroponics/fermenting_barrel.dm
@@ -17,7 +17,7 @@
/obj/structure/fermenting_barrel/examine(mob/user)
. = ..()
- to_chat(user, "It is currently [open ? "open, letting you pour liquids in." : "closed, letting you draw liquids from the tap."] ")
+ . += "It is currently [open ? "open, letting you pour liquids in." : "closed, letting you draw liquids from the tap."] "
/obj/structure/fermenting_barrel/proc/makeWine(obj/item/reagent_containers/food/snacks/grown/G)
if(G.reagents)
diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm
index b486aa629bb..17246d6cba1 100644
--- a/code/modules/hydroponics/gene_modder.dm
+++ b/code/modules/hydroponics/gene_modder.dm
@@ -33,14 +33,14 @@
component_parts += new /obj/item/stock_parts/manipulator(null)
RefreshParts()
-/obj/machinery/plantgenes/upgraded/New()
+/obj/machinery/plantgenes/seedvault/New()
..()
component_parts = list()
- component_parts += new /obj/item/circuitboard/plantgenes(null)
+ component_parts += new /obj/item/circuitboard/plantgenes/vault(null)
component_parts += new /obj/item/stock_parts/console_screen(null)
- component_parts += new /obj/item/stock_parts/scanning_module/phasic(null)
- component_parts += new /obj/item/stock_parts/micro_laser/ultra(null)
- component_parts += new /obj/item/stock_parts/manipulator/pico(null)
+ component_parts += new /obj/item/stock_parts/scanning_module(null)
+ component_parts += new /obj/item/stock_parts/micro_laser(null)
+ component_parts += new /obj/item/stock_parts/manipulator(null)
RefreshParts()
/obj/machinery/plantgenes/Destroy()
@@ -73,6 +73,14 @@
var/wratemod = ML.rating * 2.5
min_wrate = Floor(10-wratemod) // 7,5,2,0 Clamps at 0 and 10 You want this low
min_wchance = 67-(ML.rating*16) // 48,35,19,3 Clamps at 0 and 67 You want this low
+ for(var/obj/item/circuitboard/plantgenes/vaultcheck in component_parts)
+ if(istype(vaultcheck, /obj/item/circuitboard/plantgenes/vault)) // TRAIT_DUMB BOTANY TUTS
+ max_potency = 100
+ max_yield = 10
+ min_production = 1
+ max_endurance = 100
+ min_wchance = 0
+ min_wrate = 0
/obj/machinery/plantgenes/update_icon()
..()
@@ -471,8 +479,8 @@
to_chat(user, "You flip the write-protect tab to [read_only ? "protected" : "unprotected"].")
/obj/item/disk/plantgene/examine(mob/user)
- ..()
- to_chat(user, "The write-protect tab is set to [read_only ? "protected" : "unprotected"].")
+ . = ..()
+ . += "The write-protect tab is set to [read_only ? "protected" : "unprotected"]."
/*
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index f2858c298f5..c83be1a3a7a 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -55,11 +55,11 @@
return 0
/obj/item/reagent_containers/food/snacks/grown/examine(user)
- ..()
+ . = ..()
if(seed)
for(var/datum/plant_gene/trait/T in seed.genes)
if(T.examine_line)
- to_chat(user, T.examine_line)
+ . += T.examine_line
/obj/item/reagent_containers/food/snacks/grown/attackby(obj/item/O, mob/user, params)
..()
diff --git a/code/modules/hydroponics/grown/cotton.dm b/code/modules/hydroponics/grown/cotton.dm
index 3fa4247f578..590831a1f9b 100644
--- a/code/modules/hydroponics/grown/cotton.dm
+++ b/code/modules/hydroponics/grown/cotton.dm
@@ -61,6 +61,7 @@
yield = 2
potency = 50
growthstages = 3
+ mutatelist = list()
growing_icon = 'icons/obj/hydroponics/growing.dmi'
icon_dead = "cotton-dead"
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index 111f727e01a..6411935596b 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -339,32 +339,32 @@
/obj/machinery/hydroponics/examine(user)
- ..()
+ . = ..()
if(myseed)
- to_chat(user, "It has [myseed.plantname] planted.")
+ . += "It has [myseed.plantname] planted."
if (dead)
- to_chat(user, "It's dead!")
+ . += "It's dead!"
else if (harvest)
- to_chat(user, "It's ready to harvest.")
+ . += "It's ready to harvest."
else if (plant_health <= (myseed.endurance / 2))
- to_chat(user, "It looks unhealthy.")
+ . += "It looks unhealthy."
else
- to_chat(user, "[src] is empty.")
+ . += "[src] is empty."
if(!self_sustaining)
- to_chat(user, "Water: [waterlevel]/[maxwater]")
- to_chat(user, "Nutrient: [nutrilevel]/[maxnutri]")
+ . += "Water: [waterlevel]/[maxwater]"
+ . += "Nutrient: [nutrilevel]/[maxnutri]"
if(self_sufficiency_progress > 0)
var/percent_progress = round(self_sufficiency_progress * 100 / self_sufficiency_req)
- to_chat(user, "Treatment for self-sustenance are [percent_progress]% complete.")
+ . += "Treatment for self-sustenance are [percent_progress]% complete."
else
- to_chat(user, "It doesn't require any water or nutrients.")
+ . += "It doesn't require any water or nutrients."
if(weedlevel >= 5)
- to_chat(user, "[src] is filled with weeds!")
+ . += "[src] is filled with weeds!"
if(pestlevel >= 5)
- to_chat(user, "[src] is filled with tiny worms!")
- to_chat(user, "") // Empty line for readability.
+ . += "[src] is filled with tiny worms!"
+ . += "" // Empty line for readability.
/obj/machinery/hydroponics/proc/weedinvasion() // If a weed growth is sufficient, this happens.
@@ -991,12 +991,12 @@
/obj/machinery/hydroponics/attack_animal(mob/living/user)
if(istype(user, /mob/living/simple_animal/diona))
if(weedlevel > 0)
- user.nutrition += weedlevel * 15
+ user.adjust_nutrition(weedlevel * 15)
adjustWeeds(-10)
update_icon()
visible_message("[user] begins rooting through [src], ripping out weeds and eating them noisily.","You begin rooting through [src], ripping out weeds and eating them noisily.")
else if(nutrilevel < 10)
- user.nutrition -= ((10 - nutrilevel) * 5)
+ user.adjust_nutrition(-((10 - nutrilevel) * 5))
adjustNutri(10)
update_icon()
visible_message("[user] secretes a trickle of green liquid from its tail, refilling [src]'s nutrient tray.","You secrete a trickle of green liquid from your tail, refilling [src]'s nutrient tray.")
diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm
index d340e6069cc..df943d6f30d 100644
--- a/code/modules/mining/equipment/kinetic_crusher.dm
+++ b/code/modules/mining/equipment/kinetic_crusher.dm
@@ -32,12 +32,12 @@
return ..()
/obj/item/twohanded/kinetic_crusher/examine(mob/living/user)
- ..()
- to_chat(user, "Mark a large creature with the destabilizing force, then hit them in melee to do [force + detonation_damage] damage.")
- to_chat(user, "Does [force + detonation_damage + backstab_bonus] damage if the target is backstabbed, instead of [force + detonation_damage].")
+ . = ..()
+ . += "Mark a large creature with the destabilizing force, then hit them in melee to do [force + detonation_damage] damage."
+ . += "Does [force + detonation_damage + backstab_bonus] damage if the target is backstabbed, instead of [force + detonation_damage]."
for(var/t in trophies)
var/obj/item/crusher_trophy/T = t
- to_chat(user, "It has \a [T] attached, which causes [T.effect_desc()].")
+ . += "It has \a [T] attached, which causes [T.effect_desc()]."
/obj/item/twohanded/kinetic_crusher/attackby(obj/item/I, mob/living/user)
if(iscrowbar(I))
@@ -191,8 +191,8 @@
var/denied_type = /obj/item/crusher_trophy
/obj/item/crusher_trophy/examine(mob/living/user)
- ..()
- to_chat(user, "Causes [effect_desc()] when attached to a kinetic crusher.")
+ . = ..()
+ . += "Causes [effect_desc()] when attached to a kinetic crusher."
/obj/item/crusher_trophy/proc/effect_desc()
return "errors"
diff --git a/code/modules/mining/equipment/lazarus_injector.dm b/code/modules/mining/equipment/lazarus_injector.dm
index 0f174ff748f..e2a7c192153 100644
--- a/code/modules/mining/equipment/lazarus_injector.dm
+++ b/code/modules/mining/equipment/lazarus_injector.dm
@@ -59,11 +59,11 @@
malfunctioning = 1
/obj/item/lazarus_injector/examine(mob/user)
- ..(user)
+ . = ..()
if(!loaded)
- to_chat(user, "[src] is empty.")
+ . += "[src] is empty."
if(malfunctioning)
- to_chat(user, "The display on [src] seems to be flickering.")
+ . += "The display on [src] seems to be flickering."
/*********************Mob Capsule*************************/
diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm
index 90908fbf666..0db80c84dab 100644
--- a/code/modules/mining/equipment/marker_beacons.dm
+++ b/code/modules/mining/equipment/marker_beacons.dm
@@ -36,9 +36,9 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
update_icon()
/obj/item/stack/marker_beacon/examine(mob/user)
- ..()
- to_chat(user, "Use in-hand to place a [singular_name].")
- to_chat(user, "Alt-click to select a color. Current color is [picked_color].")
+ . = ..()
+ . += "Use in-hand to place a [singular_name]."
+ . += "Alt-click to select a color. Current color is [picked_color]."
/obj/item/stack/marker_beacon/update_icon()
icon_state = "[initial(icon_state)][lowertext(picked_color)]"
@@ -93,8 +93,8 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
qdel(src)
/obj/structure/marker_beacon/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to select a color. Current color is [picked_color].")
+ . = ..()
+ . += "Alt-click to select a color. Current color is [picked_color]."
/obj/structure/marker_beacon/update_icon()
while(!picked_color || !GLOB.marker_beacon_colors[picked_color])
diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm
index 68a7270477c..e01fc32511c 100644
--- a/code/modules/mining/equipment/survival_pod.dm
+++ b/code/modules/mining/equipment/survival_pod.dm
@@ -27,8 +27,8 @@
/obj/item/survivalcapsule/examine(mob/user)
. = ..()
get_template()
- to_chat(user, "This capsule has the [template.name] stored.")
- to_chat(user, template.description)
+ . += "This capsule has the [template.name] stored."
+ . += template.description
/obj/item/survivalcapsule/attack_self()
// Can't grab when capsule is New() because templates aren't loaded then
diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm
index 6591f3ed56f..1ce1350a73a 100644
--- a/code/modules/mining/fulton.dm
+++ b/code/modules/mining/fulton.dm
@@ -14,8 +14,8 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
var/max_force_fulton = MOVE_FORCE_STRONG
/obj/item/extraction_pack/examine(mob/user)
- ..()
- to_chat(user, "It has [uses_left] use\s remaining.")
+ . = ..()
+ . += "It has [uses_left] use\s remaining."
/obj/item/extraction_pack/attack_self(mob/user)
var/list/possible_beacons = list()
diff --git a/code/modules/mining/lavaland/loot/hierophant_loot.dm b/code/modules/mining/lavaland/loot/hierophant_loot.dm
index d7f47baed1d..a25d822af8c 100644
--- a/code/modules/mining/lavaland/loot/hierophant_loot.dm
+++ b/code/modules/mining/lavaland/loot/hierophant_loot.dm
@@ -27,8 +27,8 @@
var/friendly_fire_check = FALSE //if the blasts we make will consider our faction against the faction of hit targets
/obj/item/hierophant_club/examine(mob/user)
- ..()
- to_chat(user, "The[beacon ? " beacon is not currently":"re is a beacon"] attached.")
+ . = ..()
+ . += "The[beacon ? " beacon is not currently":"re is a beacon"] attached."
/obj/item/hierophant_club/suicide_act(mob/living/user)
atom_say("Xverwpsgexmrk...")
@@ -114,6 +114,9 @@
if(user.is_in_active_hand(src) && user.is_in_inactive_hand(src)) //you need to hold the staff to teleport
to_chat(user, "You need to hold the club in your hands to [beacon ? "teleport with it":"detach the beacon"]!")
return
+ if(is_in_teleport_proof_area(user))
+ to_chat(user, "[src] sparks and fizzles.")
+ return
if(!beacon || QDELETED(beacon))
if(isturf(user.loc))
user.visible_message("[user] starts fiddling with [src]'s pommel...", \
diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm
index 7e6fea76188..7c26b4900c9 100644
--- a/code/modules/mining/lavaland/loot/tendril_loot.dm
+++ b/code/modules/mining/lavaland/loot/tendril_loot.dm
@@ -312,6 +312,10 @@
to_chat(user, "[src] fizzles uselessly.")
return
+ if(is_in_teleport_proof_area(user) || is_in_teleport_proof_area(linked))
+ to_chat(user, "[src] sparks and fizzles.")
+ return
+
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(1, 0, user.loc)
smoke.start()
diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm
index 8f85908a995..b20bcb347de 100644
--- a/code/modules/mining/machine_vending.dm
+++ b/code/modules/mining/machine_vending.dm
@@ -275,8 +275,8 @@
..()
/obj/item/card/mining_point_card/examine(mob/user)
- ..(user)
- to_chat(user, "There's [points] points on the card.")
+ . = ..()
+ . += "There's [points] points on the card."
/**********************Conscription Kit**********************/
diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm
index 789a241a34a..88926ca708f 100644
--- a/code/modules/mining/ores_coins.dm
+++ b/code/modules/mining/ores_coins.dm
@@ -322,6 +322,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
var/string_attached
var/list/sideslist = list("heads","tails")
var/cmineral = null
+ var/name_by_cmineral = TRUE
var/cooldown = 0
var/credits = 10
@@ -330,7 +331,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
pixel_y = rand(0,8)-8
icon_state = "coin_[cmineral]_[sideslist[1]]"
- if(cmineral)
+ if(cmineral && name_by_cmineral)
name = "[cmineral] coin"
/obj/item/coin/gold
@@ -405,6 +406,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
desc = "A novelty coin that helps the heart know what hard evidence cannot prove."
sideslist = list("valid", "salad")
credits = 20
+ name_by_cmineral = FALSE
/obj/item/coin/antagtoken/syndicate
name = "syndicate coin"
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index fc4a14c6e6d..b00883c4cdd 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -97,9 +97,9 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
return ..()
/mob/dead/observer/examine(mob/user)
- ..()
+ . = ..()
if(!invisibility)
- to_chat(user, "It seems extremely obvious.")
+ . += "It seems extremely obvious."
// This seems stupid, but it's the easiest way to avoid absolutely ridiculous shit from happening
// Copying an appearance directly from a mob includes it's verb list, it's invisibility, it's alpha, and it's density
diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm
index 4fbd405abf9..f4832e20384 100644
--- a/code/modules/mob/living/carbon/alien/alien_defense.dm
+++ b/code/modules/mob/living/carbon/alien/alien_defense.dm
@@ -71,4 +71,13 @@ In all, this is a lot like the monkey code. /N
adjustStaminaLoss(damage)
/mob/living/carbon/alien/acid_act(acidpwr, acid_volume)
- return 0//aliens are immune to acid.
\ No newline at end of file
+ return 0 //aliens are immune to acid.
+
+/mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M)
+ if(..()) //successful slime attack
+ var/damage = rand(5, 35)
+ if(M.is_adult)
+ damage = rand(10, 40)
+ adjustBruteLoss(damage)
+ add_attack_logs(src, M, "Slime'd for [damage] damage")
+ updatehealth("slime attack")
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index 788b8aa936d..d6bb6c6c1ac 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -65,15 +65,6 @@
take_overall_damage(b_loss, f_loss)
-/mob/living/carbon/alien/humanoid/attack_slime(mob/living/carbon/slime/M)
- ..()
- var/damage = rand(5, 35)
- if(M.is_adult)
- damage = rand(10, 40)
- adjustBruteLoss(damage)
- add_attack_logs(src, M, "Slime'd for [damage] damage")
- return
-
/mob/living/carbon/alien/humanoid/restrained()
if(handcuffed)
return 1
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 5ebaaffac0c..1ba5e4530ff 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -71,16 +71,6 @@
/mob/living/carbon/alien/larva/attack_ui(slot_id)
return
-/mob/living/carbon/alien/larva/attack_slime(mob/living/carbon/slime/M)
- ..()
- var/damage = rand(5, 35)
- if(M.is_adult)
- damage = rand(20, 40)
- adjustBruteLoss(damage)
- add_attack_logs(src, M, "Slime'd for [damage] damage")
- updatehealth()
- return
-
/mob/living/carbon/alien/larva/restrained()
return 0
diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm
index 65e4fd3136a..2c06923bac3 100644
--- a/code/modules/mob/living/carbon/alien/special/facehugger.dm
+++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm
@@ -47,16 +47,15 @@ var/const/MAX_ACTIVE_TIME = 400
Attach(M)
/obj/item/clothing/mask/facehugger/examine(mob/user)
- ..(user)
- if(!real)//So that giant red text about probisci doesn't show up.
- return
- switch(stat)
- if(DEAD,UNCONSCIOUS)
- to_chat(user, "[src] is not moving.")
- if(CONSCIOUS)
- to_chat(user, "[src] seems to be active!")
- if(sterile)
- to_chat(user, "It looks like the proboscis has been removed.")
+ . = ..()
+ if(real)//So that giant red text about probisci doesn't show up for fake ones
+ switch(stat)
+ if(DEAD,UNCONSCIOUS)
+ . += "[src] is not moving."
+ if(CONSCIOUS)
+ . += "[src] seems to be active!"
+ if(sterile)
+ . += "It looks like the proboscis has been removed."
/obj/item/clothing/mask/facehugger/attackby(obj/item/O,mob/m, params)
if(O.force)
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index 6b194315f1d..ffe70211a37 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -169,7 +169,7 @@
/obj/item/mmi/examine(mob/user)
. = ..()
if(radio)
- to_chat(user, "A radio is installed on [src].")
+ . += "A radio is installed on [src]."
/obj/item/mmi/proc/install_radio()
radio = new(src)
diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm
index 14135bccc41..e55800ea184 100644
--- a/code/modules/mob/living/carbon/brain/brain.dm
+++ b/code/modules/mob/living/carbon/brain/brain.dm
@@ -41,7 +41,7 @@
return 1
if(istype(other, /mob/living/carbon/human))
return 1
- if(istype(other, /mob/living/carbon/slime))
+ if(istype(other, /mob/living/simple_animal/slime))
return 1
return ..()
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index af1d7680aca..3017257069a 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -50,11 +50,11 @@
to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a [initial(src.name)].")
/obj/item/organ/internal/brain/examine(mob/user) // -- TLE
- ..(user)
+ . = ..()
if(brainmob && brainmob.client)//if thar be a brain inside... the brain.
- to_chat(user, "You can feel the small spark of life still left in this one.")
+ . += "You can feel the small spark of life still left in this one."
else
- to_chat(user, "This one seems particularly lifeless. Perhaps it will regain some of its luster later..")
+ . += "This one seems particularly lifeless. Perhaps it will regain some of its luster later.."
/obj/item/organ/internal/brain/remove(var/mob/living/user,special = 0)
if(dna)
diff --git a/code/modules/mob/living/carbon/brain/robotic_brain.dm b/code/modules/mob/living/carbon/brain/robotic_brain.dm
index 6528d9c252e..320152a7bee 100644
--- a/code/modules/mob/living/carbon/brain/robotic_brain.dm
+++ b/code/modules/mob/living/carbon/brain/robotic_brain.dm
@@ -166,12 +166,9 @@
/obj/item/mmi/robotic_brain/examine(mob/user)
- to_chat(user, "Its speaker is turned [silenced ? "off" : "on"].")
- to_chat(user, "*---------*")
+ . += "Its speaker is turned [silenced ? "off" : "on"]."
+ . += "*---------*"
. = ..()
- if(!.)
- to_chat(user, "*---------*")
- return
var/list/msg = list("")
@@ -187,7 +184,7 @@
else
msg += "It appears to be completely inactive.\n"
msg += "*---------*"
- to_chat(user, msg.Join(""))
+ . += msg.Join("")
/obj/item/mmi/robotic_brain/emp_act(severity)
if(!brainmob)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index fc851c920d4..da23de1f6ad 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -26,9 +26,9 @@
. = ..()
if(.)
if(nutrition && stat != DEAD)
- nutrition -= hunger_drain / 10
+ adjust_nutrition(-(hunger_drain * 0.1))
if(m_intent == MOVE_INTENT_RUN)
- nutrition -= hunger_drain / 10
+ adjust_nutrition(-(hunger_drain * 0.1))
if((FAT in mutations) && m_intent == MOVE_INTENT_RUN && bodytemperature <= 360)
bodytemperature += 2
@@ -110,7 +110,7 @@
else
if(T)
T.add_vomit_floor()
- nutrition -= lost_nutrition
+ adjust_nutrition(-lost_nutrition)
if(stun)
adjustToxLoss(-3)
T = get_step(T, dir)
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 161fbd412d1..648d4c53503 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -48,16 +48,25 @@
return 1
return 0
-/mob/living/carbon/attack_slime(mob/living/carbon/slime/M)
- if(..())
- var/power = M.powerlevel + rand(0,3)
- Weaken(power)
- Stuttering(power)
- Stun(power)
- var/stunprob = M.powerlevel * 7 + 10
- if(prob(stunprob) && M.powerlevel >= 8)
- adjustFireLoss(M.powerlevel * rand(6,10))
- updatehealth("slime attack")
+/mob/living/carbon/attack_slime(mob/living/simple_animal/slime/M)
+ if(..()) //successful slime attack
+ if(M.powerlevel > 0)
+ var/stunprob = M.powerlevel * 7 + 10 // 17 at level 1, 80 at level 10
+ if(prob(stunprob))
+ M.powerlevel -= 3
+ if(M.powerlevel < 0)
+ M.powerlevel = 0
+
+ visible_message("The [M.name] has shocked [src]!", "The [M.name] has shocked you!")
+
+ do_sparks(5, TRUE, src)
+ var/power = M.powerlevel + rand(0,3)
+ Stun(power)
+ if(stuttering < power)
+ stuttering = power
+ if (prob(stunprob) && M.powerlevel >= 8)
+ adjustFireLoss(M.powerlevel * rand(6,10))
+ updatehealth("slime attack")
return 1
/mob/living/carbon/is_mouth_covered(head_only = FALSE, mask_only = FALSE)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 1862fe5cffa..7a18e881eb6 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -374,7 +374,7 @@
pose = addtext(pose,".") //Makes sure all emotes end with a period.
msg += "\n[p_they(TRUE)] [p_are()] [pose]"
- to_chat(user, msg)
+ . = list(msg)
//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
/proc/hasHUD(mob/M as mob, hudtype)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 4a4326d7b57..40069656822 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1573,7 +1573,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
threatcount += 2
//Check for dresscode violations
- if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard))
+ if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/shielded/wizard))
threatcount += 2
@@ -1896,6 +1896,16 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
.["Make superhero"] = "?_src_=vars;makesuper=[UID()]"
. += "---"
+/mob/living/carbon/human/adjust_nutrition(change)
+ if(NO_HUNGER in dna.species.species_traits)
+ return FALSE
+ return ..()
+
+/mob/living/carbon/human/set_nutrition(change)
+ if(NO_HUNGER in dna.species.species_traits)
+ return FALSE
+ return ..()
+
/mob/living/carbon/human/proc/special_post_clone_handling()
if(mind && mind.assigned_role == "Cluwne") //HUNKE your suffering never stops
makeCluwne()
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 650b1eb5663..b68b77e77de 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -597,22 +597,22 @@ emp_act
apply_damage(damage, M.melee_damage_type, affecting, armor)
updatehealth("animal attack")
-/mob/living/carbon/human/attack_slime(mob/living/carbon/slime/M)
- ..()
- var/damage = rand(1, 3)
+/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M)
+ if(..()) //successful slime attack
+ var/damage = rand(5, 25)
+ if(M.is_adult)
+ damage = rand(10, 35)
- if(M.is_adult)
- damage = rand(10, 35)
- else
- damage = rand(5, 25)
+ if(check_shields(M, damage, "the [M.name]"))
+ return FALSE
- var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot")
+ var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot")
- var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
- var/armor_block = run_armor_check(affecting, "melee")
- apply_damage(damage, BRUTE, affecting, armor_block)
-
- return
+ var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
+ if(!affecting)
+ affecting = get_organ("chest")
+ var/armor_block = run_armor_check(affecting, "melee")
+ apply_damage(damage, BRUTE, affecting, armor_block)
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
if(M.occupant.a_intent == INTENT_HARM)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index bc3e1fdb3bd..2643d1f3102 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -597,54 +597,55 @@
if(status_flags & GODMODE)
return 0 //godmode
- //The fucking FAT mutation is the greatest shit ever. It makes everyone so hot and bothered.
- if(CAN_BE_FAT in dna.species.species_traits)
- if(FAT in mutations)
- if(overeatduration < 100)
- becomeSlim()
- else
- if(overeatduration > 500)
- becomeFat()
-
- // nutrition decrease
- if(nutrition > 0 && stat != DEAD)
- // THEY HUNGER
- var/hunger_rate = hunger_drain
- if(satiety > 0)
- satiety--
- if(satiety < 0)
- satiety++
- if(prob(round(-satiety/40)))
- Jitter(5)
- hunger_rate = 3 * hunger_drain
- nutrition = max(0, nutrition - hunger_rate)
-
- if(nutrition > NUTRITION_LEVEL_FULL)
- if(overeatduration < 600) //capped so people don't take forever to unfat
- overeatduration++
-
- else
- if(overeatduration > 1)
- if(OBESITY in mutations)
- overeatduration -= 1 // Those with obesity gene take twice as long to unfat
+ if(!(NO_HUNGER in dna.species.species_traits))
+ //The fucking FAT mutation is the greatest shit ever. It makes everyone so hot and bothered.
+ if(CAN_BE_FAT in dna.species.species_traits)
+ if(FAT in mutations)
+ if(overeatduration < 100)
+ becomeSlim()
else
- overeatduration -= 2
+ if(overeatduration > 500)
+ becomeFat()
- //metabolism change
- if(nutrition > NUTRITION_LEVEL_FAT)
- metabolism_efficiency = 1
- else if(nutrition > NUTRITION_LEVEL_FED && satiety > 80)
- if(metabolism_efficiency != 1.25)
- to_chat(src, "You feel vigorous.")
- metabolism_efficiency = 1.25
- else if(nutrition < NUTRITION_LEVEL_STARVING + 50)
- if(metabolism_efficiency != 0.8)
- to_chat(src, "You feel sluggish.")
- metabolism_efficiency = 0.8
- else
- if(metabolism_efficiency == 1.25)
- to_chat(src, "You no longer feel vigorous.")
- metabolism_efficiency = 1
+ // nutrition decrease
+ if(nutrition > 0 && stat != DEAD)
+ // THEY HUNGER
+ var/hunger_rate = hunger_drain
+ if(satiety > 0)
+ satiety--
+ if(satiety < 0)
+ satiety++
+ if(prob(round(-satiety/40)))
+ Jitter(5)
+ hunger_rate = 3 * hunger_drain
+ adjust_nutrition(-hunger_rate)
+
+ if(nutrition > NUTRITION_LEVEL_FULL)
+ if(overeatduration < 600) //capped so people don't take forever to unfat
+ overeatduration++
+
+ else
+ if(overeatduration > 1)
+ if(OBESITY in mutations)
+ overeatduration -= 1 // Those with obesity gene take twice as long to unfat
+ else
+ overeatduration -= 2
+
+ //metabolism change
+ if(nutrition > NUTRITION_LEVEL_FAT)
+ metabolism_efficiency = 1
+ else if(nutrition > NUTRITION_LEVEL_FED && satiety > 80)
+ if(metabolism_efficiency != 1.25)
+ to_chat(src, "You feel vigorous.")
+ metabolism_efficiency = 1.25
+ else if(nutrition < NUTRITION_LEVEL_STARVING + 50)
+ if(metabolism_efficiency != 0.8)
+ to_chat(src, "You feel sluggish.")
+ metabolism_efficiency = 0.8
+ else
+ if(metabolism_efficiency == 1.25)
+ to_chat(src, "You no longer feel vigorous.")
+ metabolism_efficiency = 1
if(drowsyness)
AdjustDrowsy(-1)
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index d3ce27a4704..1e753279059 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -814,6 +814,8 @@
H.healthdoll.cached_healthdoll_overlays = new_overlays
/datum/species/proc/handle_hud_icons_nutrition(mob/living/carbon/human/H)
+ if(NO_HUNGER in species_traits)
+ return FALSE
if(H.mind && H.mind.vampire && (H.mind in SSticker.mode.vampires)) //Vampires
switch(H.nutrition)
if(NUTRITION_LEVEL_FULL to INFINITY)
diff --git a/code/modules/mob/living/carbon/human/species/abductor.dm b/code/modules/mob/living/carbon/human/species/abductor.dm
index 64c5a4aa0b3..33b94cbabe0 100644
--- a/code/modules/mob/living/carbon/human/species/abductor.dm
+++ b/code/modules/mob/living/carbon/human/species/abductor.dm
@@ -11,13 +11,14 @@
"liver" = /obj/item/organ/internal/liver,
"kidneys" = /obj/item/organ/internal/kidneys,
"brain" = /obj/item/organ/internal/brain/abductor,
- "appendix" = /obj/item/organ/internal/appendix,
"eyes" = /obj/item/organ/internal/eyes/abductor //3 darksight.
)
- species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS, NO_EXAMINE)
+ species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS, NO_HUNGER, NO_EXAMINE)
dies_at_threshold = TRUE
+ taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE
+
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
diff --git a/code/modules/mob/living/carbon/human/species/diona.dm b/code/modules/mob/living/carbon/human/species/diona.dm
index 40fc2b001df..48664341623 100644
--- a/code/modules/mob/living/carbon/human/species/diona.dm
+++ b/code/modules/mob/living/carbon/human/species/diona.dm
@@ -91,9 +91,9 @@
H.clear_alert("nolight")
else
H.throw_alert("nolight", /obj/screen/alert/nolight)
- H.nutrition += light_amount * 10
+ H.adjust_nutrition(light_amount * 10)
if(H.nutrition > NUTRITION_LEVEL_ALMOST_FULL)
- H.nutrition = NUTRITION_LEVEL_ALMOST_FULL
+ H.set_nutrition(NUTRITION_LEVEL_ALMOST_FULL)
if(light_amount > 0.2 && !H.suiciding) //if there's enough light, heal
if(!pod && H.health <= 0)
return
diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm
index b9130433613..0328e99a6a0 100644
--- a/code/modules/mob/living/carbon/human/species/golem.dm
+++ b/code/modules/mob/living/carbon/human/species/golem.dm
@@ -341,8 +341,7 @@
heat_level_2 = 340
heat_level_3 = 400
- dietflags = 0 //Regenerate nutrition in light, no diet necessary
- taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE
+ dietflags = DIET_HERB // Plants eat...plants?
info_text = "As a Wooden Golem, you have plant-like traits: you take damage from extreme temperatures, can be set on fire, and have lower armor than a normal golem. You regenerate when in the light and wither in the darkness."
prefix = "Wooden"
@@ -361,9 +360,9 @@
H.clear_alert("nolight")
else
H.throw_alert("nolight", /obj/screen/alert/nolight)
- H.nutrition += light_amount * 10
+ H.adjust_nutrition(light_amount * 10)
if(H.nutrition > NUTRITION_LEVEL_ALMOST_FULL)
- H.nutrition = NUTRITION_LEVEL_ALMOST_FULL
+ H.set_nutrition(NUTRITION_LEVEL_ALMOST_FULL)
if(light_amount > 0.2 && !H.suiciding) //if there's enough light, heal
H.adjustBruteLoss(-1)
H.adjustFireLoss(-1)
diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm
index e4ba4349202..d925e2ef1d9 100644
--- a/code/modules/mob/living/carbon/human/species/plasmaman.dm
+++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm
@@ -1,4 +1,4 @@
-/datum/species/plasmaman // /vg/
+/datum/species/plasmaman
name = "Plasmaman"
name_plural = "Plasmamen"
icobase = 'icons/mob/human_races/r_plasmaman_sb.dmi'
@@ -6,12 +6,14 @@
dangerous_existence = TRUE //So so much
//language = "Clatter"
- species_traits = list(IS_WHITELISTED, RADIMMUNE, NO_BLOOD, NOTRANSSTING)
+ species_traits = list(IS_WHITELISTED, RADIMMUNE, NO_BLOOD, NO_HUNGER, NOTRANSSTING)
forced_heartattack = TRUE // Plasmamen have no blood, but they should still get heart-attacks
skinned_type = /obj/item/stack/sheet/mineral/plasma // We're low on plasma, R&D! *eyes plasmaman co-worker intently*
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
+ taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE //skeletons can't taste anything
+
butt_sprite = "plasma"
breathid = "tox"
@@ -34,7 +36,6 @@
"liver" = /obj/item/organ/internal/liver/plasmaman,
"kidneys" = /obj/item/organ/internal/kidneys/plasmaman,
"brain" = /obj/item/organ/internal/brain/plasmaman,
- "appendix" = /obj/item/organ/internal/appendix,
"eyes" = /obj/item/organ/internal/eyes/plasmaman
)
diff --git a/code/modules/mob/living/carbon/human/species/shadowling.dm b/code/modules/mob/living/carbon/human/species/shadowling.dm
index f65aedb530b..d05c358ce73 100644
--- a/code/modules/mob/living/carbon/human/species/shadowling.dm
+++ b/code/modules/mob/living/carbon/human/species/shadowling.dm
@@ -9,7 +9,7 @@
blood_color = "#555555"
flesh_color = "#222222"
- species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NOGUNS, NO_EXAMINE) //Can't use guns due to muzzle flash
+ species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NOGUNS, NO_HUNGER, NO_EXAMINE) //Can't use guns due to muzzle flash
burn_mod = 1.5 //1.5x burn damage, 2x is excessive
heatmod = 1.5
@@ -24,7 +24,6 @@
if(!H.weakeyes)
H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs
var/light_amount = 0
- H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry
if(isturf(H.loc))
var/turf/T = H.loc
light_amount = T.get_lumcount() * 10
@@ -60,7 +59,7 @@
blood_color = "#CCCCCC"
flesh_color = "#AAAAAA"
- species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NO_EXAMINE)
+ species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NO_HUNGER, NO_EXAMINE)
burn_mod = 1.1
heatmod = 1.1
@@ -68,7 +67,6 @@
if(!H.weakeyes)
H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs
var/light_amount = 0
- H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry
if(isturf(H.loc))
var/turf/T = H.loc
light_amount = T.get_lumcount() * 10
diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm
index 2ce5839123b..af779483666 100644
--- a/code/modules/mob/living/carbon/human/species/skeleton.dm
+++ b/code/modules/mob/living/carbon/human/species/skeleton.dm
@@ -10,10 +10,12 @@
blood_color = "#FFFFFF"
flesh_color = "#E6E6C6"
- species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE, PIERCEIMMUNE)
+ species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE, NO_HUNGER, PIERCEIMMUNE)
dies_at_threshold = TRUE
skinned_type = /obj/item/stack/sheet/bone
+ taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE //skeletons can't taste anything
+
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm
index 37b38de361c..76e7ce2afee 100644
--- a/code/modules/mob/living/carbon/human/species/slime.dm
+++ b/code/modules/mob/living/carbon/human/species/slime.dm
@@ -25,8 +25,7 @@
male_cough_sounds = list('sound/effects/slime_squish.ogg')
female_cough_sounds = list('sound/effects/slime_squish.ogg')
- species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_INTORGANS, NO_SCAN)
- dies_at_threshold = TRUE
+ species_traits = list(LIPS, IS_WHITELISTED, NO_SCAN)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_SKIN_COLOR | NO_EYES
dietflags = DIET_CARN
@@ -35,16 +34,29 @@
flesh_color = "#5fe8b1"
blood_color = "#0064C8"
exotic_blood = "water"
- blood_damage_type = TOX
butt_sprite = "slime"
//Has default darksight of 2.
has_organ = list(
- "brain" = /obj/item/organ/internal/brain/slime
+ "brain" = /obj/item/organ/internal/brain/slime,
+ "osmatic pressure regulator" = /obj/item/organ/internal/heart/slime,
+ "gas exchange membrane" = /obj/item/organ/internal/lungs/slime
)
mutantears = null
-
+ has_limbs = list(
+ "chest" = list("path" = /obj/item/organ/external/chest/unbreakable),
+ "groin" = list("path" = /obj/item/organ/external/groin/unbreakable),
+ "head" = list("path" = /obj/item/organ/external/head/unbreakable),
+ "l_arm" = list("path" = /obj/item/organ/external/arm/unbreakable),
+ "r_arm" = list("path" = /obj/item/organ/external/arm/right/unbreakable),
+ "l_leg" = list("path" = /obj/item/organ/external/leg/unbreakable),
+ "r_leg" = list("path" = /obj/item/organ/external/leg/right/unbreakable),
+ "l_hand" = list("path" = /obj/item/organ/external/hand/unbreakable),
+ "r_hand" = list("path" = /obj/item/organ/external/hand/right/unbreakable),
+ "l_foot" = list("path" = /obj/item/organ/external/foot/unbreakable),
+ "r_foot" = list("path" = /obj/item/organ/external/foot/right/unbreakable)
+ )
suicide_messages = list(
"is melting into a puddle!",
"is ripping out their own core!",
@@ -171,7 +183,7 @@
H.update_body()
H.updatehealth()
H.UpdateDamageIcon()
- H.nutrition -= SLIMEPERSON_HUNGERCOST
+ H.adjust_nutrition(-SLIMEPERSON_HUNGERCOST)
H.visible_message("[H] finishes regrowing [H.p_their()] missing [new_limb]!", "You finish regrowing your [limb_select]")
else
to_chat(H, "You need to hold still in order to regrow a limb!")
diff --git a/code/modules/mob/living/carbon/human/species/unathi.dm b/code/modules/mob/living/carbon/human/species/unathi.dm
index 7ab0f9cbec9..6240e2673bd 100644
--- a/code/modules/mob/living/carbon/human/species/unathi.dm
+++ b/code/modules/mob/living/carbon/human/species/unathi.dm
@@ -19,6 +19,7 @@
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_BODY_MARKINGS | HAS_HEAD_MARKINGS | HAS_SKIN_COLOR | HAS_ALT_HEADS | TAIL_WAGGING
dietflags = DIET_CARN
+ taste_sensitivity = TASTE_SENSITIVITY_SHARP
cold_level_1 = 280 //Default 260 - Lower is better
cold_level_2 = 220 //Default 200
@@ -110,7 +111,7 @@
name_plural = "Ash Walkers"
blurb = "These reptillian creatures appear to be related to the Unathi, but seem significantly less evolved. \
- They roam the wastes of Lavaland, worshipping a dead city and capturing unsuspecting miners."
+ They roam the wastes of Lavaland, worshipping a dead city and capturing unsuspecting miners."
language = "Sinta'unathi"
default_language = "Sinta'unathi"
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 05dfbd0e302..eeda9f87461 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -893,6 +893,11 @@ var/global/list/damage_icon_parts = list()
bloodsies.color = wear_suit.blood_color
standing.overlays += bloodsies
+
+ var/special_overlays = wear_suit.special_overlays()
+ if(special_overlays)
+ standing.overlays += special_overlays
+
standing.alpha = wear_suit.alpha
standing.color = wear_suit.color
overlays_standing[SUIT_LAYER] = standing
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index c5cbbc0b1d3..a9263f58ea2 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -253,7 +253,7 @@
continue
if(times_fired % 3 == 1)
M.adjustBruteLoss(5)
- nutrition += 10
+ adjust_nutrition(10)
//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
/mob/living/carbon/handle_status_effects()
diff --git a/code/modules/mob/living/carbon/slime/death.dm b/code/modules/mob/living/carbon/slime/death.dm
deleted file mode 100644
index 055f972df07..00000000000
--- a/code/modules/mob/living/carbon/slime/death.dm
+++ /dev/null
@@ -1,21 +0,0 @@
-/mob/living/carbon/slime/death(gibbed)
- // Only execute the below if we successfully died
- . = ..()
- if(!.)
- return FALSE
- if(!gibbed)
- if(is_adult)
- var/mob/living/carbon/slime/M = new /mob/living/carbon/slime(loc)
- M.colour = colour
- M.rabid = 1
- is_adult = 0
- maxHealth = 150
- revive()
- regenerate_icons()
- number = rand(1, 1000)
- name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
- return
- else
- visible_message("The [name] seizes up and falls limp...")
- icon_state = "[colour] baby slime dead"
- overlays.Cut()
diff --git a/code/modules/mob/living/carbon/slime/examine.dm b/code/modules/mob/living/carbon/slime/examine.dm
deleted file mode 100644
index 4dd67695e2a..00000000000
--- a/code/modules/mob/living/carbon/slime/examine.dm
+++ /dev/null
@@ -1,45 +0,0 @@
-/mob/living/carbon/slime/examine(mob/user)
- to_chat(user, "*---------*")
- ..(user)
- var/msg = ""
- if(src.stat == DEAD)
- msg += "It is limp and unresponsive.\n"
- else
- if(src.getBruteLoss())
- msg += ""
- if(src.getBruteLoss() < 40)
- msg += "It has some punctures in its flesh!"
- else
- msg += "It has severe punctures and tears in its flesh!"
- msg += "\n"
-
- switch(powerlevel)
-
- if(2 to 3)
- msg += "It is flickering gently with a little electrical activity.\n"
-
- if(4 to 5)
- msg += "It is glowing gently with moderate levels of electrical activity.\n"
-
- if(6 to 9)
- msg += "It is glowing brightly with high levels of electrical activity.\n"
-
- if(10)
- msg += "It is radiating with massive levels of electrical activity!\n"
-
- msg += ""
- switch(wetlevel)
- if(1)
- msg += "It looks a bit damp.\n"
- if(2)
- msg += "It looks a little bit wet.\n"
- if(3)
- msg += "It looks wet.\n"
- if(4)
- msg += "It looks very wet.\n"
- if(5)
- msg += "It looks absolutely soaked.\n"
- msg += ""
-
- msg += "*---------*"
- to_chat(user, msg)
diff --git a/code/modules/mob/living/carbon/slime/life.dm b/code/modules/mob/living/carbon/slime/life.dm
deleted file mode 100644
index e3bfcb74431..00000000000
--- a/code/modules/mob/living/carbon/slime/life.dm
+++ /dev/null
@@ -1,570 +0,0 @@
-/mob/living/carbon/slime
- var/AIproc = 0 // determines if the AI loop is activated
- var/Atkcool = 0 // attack cooldown
- var/Tempstun = 0 // temporary temperature stuns
- var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while
- var/SStun = 0 // stun variable
-
-/mob/living/carbon/slime/Life(seconds, times_fired)
- if(..())
- handle_nutrition()
- handle_targets()
- if(!ckey)
- handle_speech_and_mood()
-
-/mob/living/carbon/slime/breathe()
- return
-
-/mob/living/carbon/slime/proc/AIprocess() // the master AI process
-
- if(AIproc || stat == DEAD || client) return
-
- var/hungry = 0
- if(nutrition < get_starve_nutrition())
- hungry = 2
- else if(nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition())
- hungry = 1
-
- AIproc = 1
-
- while(AIproc && stat != 2 && (attacked || hungry || rabid || Victim))
- if(Victim) // can't eat AND have this little process at the same time
- break
-
- if(!Target || client)
- break
-
- if(Target.health <= -70 || Target.stat == 2)
- Target = null
- AIproc = 0
- break
-
- if(Target)
- for(var/mob/living/carbon/slime/M in view(1,Target))
- if(M.Victim == Target)
- Target = null
- AIproc = 0
- break
- if(!AIproc)
- break
-
- if(Target in view(1,src))
- if(istype(Target, /mob/living/silicon))
- if(!Atkcool)
- Atkcool = 1
- spawn(45)
- Atkcool = 0
-
- if(Target.Adjacent(src))
- Target.attack_slime(src)
- return
- if(!Target.lying && prob(80))
-
- if(Target.client && Target.health >= 20)
- if(!Atkcool)
- Atkcool = 1
- spawn(45)
- Atkcool = 0
-
- if(Target.Adjacent(src))
- Target.attack_slime(src)
-
- else
- if(!Atkcool && Target.Adjacent(src))
- Feedon(Target)
-
- else
- if(!Atkcool && Target.Adjacent(src))
- Feedon(Target)
-
- else
- if(Target in view(7, src))
- if(!Target.Adjacent(src)) // Bug of the month candidate: slimes were attempting to move to target only if it was directly next to them, which caused them to target things, but not approach them
- step_to(src, Target)
- sleep(5)
-
- else
- Target = null
- AIproc = 0
- break
-
- var/sleeptime = movement_delay()
- if(sleeptime <= 0) sleeptime = 1
-
- sleep(sleeptime + 2) // this is about as fast as a player slime can go
-
- AIproc = 0
-
-/mob/living/carbon/slime/handle_environment(datum/gas_mixture/environment)
- if(!environment)
- adjustToxLoss(rand(10,20))
- return
-
- //var/environment_heat_capacity = environment.heat_capacity()
- var/loc_temp = T0C
- if(istype(get_turf(src), /turf/space))
- //environment_heat_capacity = loc:heat_capacity
- var/turf/heat_turf = get_turf(src)
- loc_temp = heat_turf.temperature
- else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
- loc_temp = loc:air_contents.temperature
- else
- loc_temp = environment.temperature
-
- //Account for massive pressure differences
- if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc
- if(bodytemperature <= (T0C - 40)) // stun temperature
- Tempstun = 1
-
- if(bodytemperature <= (T0C - 50)) // hurt temperature
- if(bodytemperature <= 50) // sqrting negative numbers is bad
- adjustToxLoss(301) //The config.health_threshold_dead is -100 by default, and slimes have 150hp (200hp for adults),
- else //so the ToxLoss needs to be 300 or above to guarrantee an instant death
- adjustToxLoss(round(sqrt(bodytemperature)) * 2)
- else
- Tempstun = 0
-
-
- /*moved after the temperature damage code so freeze beams can instantly kill slimes -Deity Link*/
- if(loc_temp < 310.15) // a cold place
- bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1)
- else // a hot place
- bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1)
-
- updatehealth("handle environment")
-
- return //TODO: DEFERRED
-
-/mob/living/carbon/slime/proc/adjust_body_temperature(current, loc_temp, boost)
- var/temperature = current
- var/difference = abs(current-loc_temp) //get difference
- var/increments// = difference/10 //find how many increments apart they are
- if(difference > 50)
- increments = difference/5
- else
- increments = difference/10
- var/change = increments*boost // Get the amount to change by (x per increment)
- var/temp_change
- if(current < loc_temp)
- temperature = min(loc_temp, temperature+change)
- else if(current > loc_temp)
- temperature = max(loc_temp, temperature-change)
- temp_change = (temperature - current)
- return temp_change
-
-/mob/living/carbon/slime/handle_chemicals_in_body()
-
- if(reagents)
- reagents.metabolize(src)
-
- if(reagents.get_reagent_amount("plasma")>=5)
- mutation_chance = min(mutation_chance + 5,50) //Prevents mutation chance going >50%
- reagents.remove_reagent("plasma", 5)
- if(reagents.get_reagent_amount("epinephrine")>=5)
- mutation_chance = max(mutation_chance - 5,0) //Prevents mutation chance going <0%
- reagents.remove_reagent("epinephrine", 5)
- updatehealth("handle chemicals in body")
-
- return //TODO: DEFERRED
-
-/mob/living/carbon/slime/handle_regular_status_updates()
-
- if(is_adult)
- health = 200 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
- else
- health = 150 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
-
- if(health < HEALTH_THRESHOLD_DEAD && check_death_method() && stat != DEAD)
- death()
- return
-
- else if(src.health <= HEALTH_THRESHOLD_CRIT && check_death_method())
-
- if(!src.reagents.has_reagent("epinephrine"))
- src.adjustOxyLoss(10)
-
- if(src.stat != DEAD)
- src.stat = UNCONSCIOUS
-
- if(prob(30)) //I think this is meant to allow slimes to starve to death
- adjustOxyLoss(-1)
- adjustToxLoss(-1)
- adjustFireLoss(-1)
- adjustCloneLoss(-1)
- adjustBruteLoss(-1)
-
- if(src.stat == DEAD)
- src.lying = 1
- else
- if(src.paralysis || src.stunned || src.weakened || (status_flags && FAKEDEATH)) //Stunned etc.
- if(src.stunned > 0)
- AdjustStunned(-1)
- src.stat = 0
- if(src.weakened > 0)
- AdjustWeakened(-1)
- src.lying = 0
- src.stat = 0
- if(src.paralysis > 0)
- AdjustParalysis(-1)
- src.lying = 0
- src.stat = 0
-
- else
- src.lying = 0
- src.stat = 0
-
- if(src.stuttering) src.stuttering = 0
-
- if(src.eye_blind)
- src.SetEyeBlind(0)
-
- src.density = !( src.lying )
-
- if(src.eye_blurry > 0)
- SetEyeBlurry(0)
-
- if(src.druggy > 0)
- SetDruggy(0)
-
- return 1
-
-/mob/living/carbon/slime/proc/handle_nutrition()
-
- if(docile) //God as my witness, I will never go hungry again
- nutrition = 700
- return
-
- if(prob(15))
- nutrition -= 1 + is_adult
-
- if(nutrition <= 0)
- nutrition = 0
- if(prob(75))
- adjustToxLoss(rand(0,5))
-
- else if(nutrition >= get_grow_nutrition() && amount_grown < 10)
- nutrition -= 20
- amount_grown++
- update_action_buttons_icon()
-
- if(amount_grown >= 10 && !Victim && !Target && !ckey)
- if(is_adult)
- Reproduce()
- else
- Evolve()
-
-/mob/living/carbon/slime/proc/add_nutrition(nutrition_to_add = 0, lastnut = 0)
- nutrition = min((nutrition + nutrition_to_add), get_max_nutrition())
- if(nutrition >= (lastnut + 50))
- if(prob(80))
- lastnut = nutrition
- powerlevel++
- if(powerlevel > 10)
- powerlevel = 10
- adjustToxLoss(-10)
-
-/mob/living/carbon/slime/proc/handle_targets()
- if(Tempstun)
- if(!Victim) // not while they're eating!
- canmove = 0
- else
- canmove = 1
-
- if(attacked > 50) attacked = 50
-
- if(attacked > 0)
- attacked--
-
- if(Discipline > 0)
-
- if(Discipline >= 5 && rabid)
- if(prob(60)) rabid = 0
-
- if(prob(10))
- Discipline--
-
- if(!client)
- if(!canmove) return
-
- if(Victim) return // if it's eating someone already, continue eating!
-
- if(Target)
- --target_patience
- if(target_patience <= 0 || SStun || Discipline || attacked || docile) // Tired of chasing or something draws out attention
- target_patience = 0
- Target = null
-
- if(AIproc && SStun) return
-
- var/hungry = 0 // determines if the slime is hungry
-
- if(nutrition < get_starve_nutrition())
- hungry = 2
- else if(nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition())
- hungry = 1
-
- if(hungry == 2 && !client) // if a slime is starving, it starts losing its friends
- if(Friends.len > 0 && prob(1))
- var/mob/nofriend = pick(Friends)
- --Friends[nofriend]
-
- if(!Target)
- if(will_hunt() && hungry || attacked || rabid) // Only add to the list if we need to
- var/list/targets = list()
-
- for(var/mob/living/L in view(7,src))
-
- if(isslime(L) || L.stat == DEAD) // Ignore other slimes and dead mobs
- continue
-
- if(L in Friends) // No eating friends!
- continue
-
- if(issilicon(L) && (rabid || attacked)) // They can't eat silicons, but they can glomp them in defence
- targets += L // Possible target found!
-
- if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men
- var/mob/living/carbon/human/H = L
- if(isslimeperson(H))
- continue
-
- if(!L.canmove) // Only one slime can latch on at a time.
- var/notarget = 0
- for(var/mob/living/carbon/slime/M in view(1,L))
- if(M.Victim == L)
- notarget = 1
- if(notarget)
- continue
-
- targets += L // Possible target found!
-
- if(targets.len > 0)
- if(attacked || rabid || hungry == 2)
- Target = targets[1] // I am attacked and am fighting back or so hungry I don't even care
- else
- for(var/mob/living/carbon/C in targets)
- if(!Discipline && prob(5))
- if(ishuman(C) || isalienadult(C))
- Target = C
- break
-
- if(islarva(C) || issmall(C))
- Target = C
- break
-
- if(Target)
- target_patience = rand(5,7)
- if(is_adult)
- target_patience += 3
-
- if(!Target) // If we have no target, we are wandering or following orders
- if(Leader)
- if(holding_still)
- holding_still = max(holding_still - 1, 0)
- else if(canmove && isturf(loc))
- step_to(src, Leader)
-
- else if(hungry)
- if(holding_still)
- holding_still = max(holding_still - hungry, 0)
- else if(canmove && isturf(loc) && prob(50))
- step(src, pick(cardinal))
-
- else
- if(holding_still)
- holding_still = max(holding_still - 1, 0)
- else if(docile && pulledby)
- holding_still = 10
- else if(canmove && isturf(loc) && prob(33))
- step(src, pick(cardinal))
- else if(!AIproc)
- spawn()
- AIprocess()
-
-/mob/living/carbon/slime/proc/handle_speech_and_mood()
- //Mood starts here
- var/newmood = ""
- if(rabid || attacked)
- newmood = "angry"
- else if(docile)
- newmood = ":3"
- else if(Target)
- newmood = "mischevous"
-
- if(!newmood)
- if(Discipline && prob(25))
- newmood = "pout"
- else if(prob(1))
- newmood = pick("sad", ":3", "pout")
-
- if((mood == "sad" || mood == ":3" || mood == "pout") && !newmood)
- if(prob(75)) newmood = mood
-
- if(newmood != mood) // This is so we don't redraw them every time
- mood = newmood
- regenerate_icons()
-
- //Speech understanding starts here
- var/to_say
- if(speech_buffer.len > 0)
- var/who = speech_buffer[1] // Who said it?
- var/phrase = speech_buffer[2] // What did they say?
- if((findtext(phrase, num2text(number)) || findtext(phrase, "slimes"))) // Talking to us
- if(findtext(phrase, "hello") || findtext(phrase, "hi"))
- to_say = pick("Hello...", "Hi...")
- else if(findtext(phrase, "follow"))
- if(Leader)
- if(Leader == who) // Already following him
- to_say = pick("Yes...", "Lead...", "Following...")
- else if(Friends[who] > Friends[Leader]) // VIVA
- Leader = who
- to_say = "Yes... I follow [who]..."
- else
- to_say = "No... I follow [Leader]..."
- else
- if(Friends[who] > 2)
- Leader = who
- to_say = "I follow..."
- else // Not friendly enough
- to_say = pick("No...", "I won't follow...")
- else if(findtext(phrase, "stop"))
- if(Victim) // We are asked to stop feeding
- if(Friends[who] > 4)
- Victim = null
- Target = null
- if(Friends[who] < 7)
- --Friends[who]
- to_say = "Grrr..." // I'm angry but I do it
- else
- to_say = "Fine..."
- else if(Target) // We are asked to stop chasing
- if(Friends[who] > 3)
- Target = null
- if(Friends[who] < 6)
- --Friends[who]
- to_say = "Grrr..." // I'm angry but I do it
- else
- to_say = "Fine..."
- else if(Leader) // We are asked to stop following
- if(Leader == who)
- to_say = "Yes... I'll stay..."
- Leader = null
- else
- if(Friends[who] > Friends[Leader])
- Leader = null
- to_say = "Yes... I'll stop..."
- else
- to_say = "No... I'll keep following..."
- else if(findtext(phrase, "stay"))
- if(Leader)
- if(Leader == who)
- holding_still = Friends[who] * 10
- to_say = "Yes... Staying..."
- else if(Friends[who] > Friends[Leader])
- holding_still = (Friends[who] - Friends[Leader]) * 10
- to_say = "Yes... Staying..."
- else
- to_say = "No... I'll keep following..."
- else
- if(Friends[who] > 2)
- holding_still = Friends[who] * 10
- to_say = "Yes... Staying..."
- else
- to_say = "No... I won't stay..."
- speech_buffer = list()
-
- //Speech starts here
- if(to_say)
- say (to_say)
- else if(prob(1))
- emote(pick("bounce","sway","light","vibrate","jiggle"))
- else
- var/t = 10
- var/slimes_near = -1 // Don't count myself
- var/dead_slimes = 0
- var/friends_near = list()
- for(var/mob/living/carbon/M in view(7,src))
- if(isslime(M))
- ++slimes_near
- if(M.stat == DEAD)
- ++dead_slimes
- if(M in Friends)
- t += 20
- friends_near += M
- if(nutrition < get_hunger_nutrition()) t += 10
- if(nutrition < get_starve_nutrition()) t += 10
- if(prob(2) && prob(t))
- var/phrases = list()
- if(Target) phrases += "[Target]... looks tasty..."
- if(nutrition < get_starve_nutrition())
- phrases += "So... hungry..."
- phrases += "Very... hungry..."
- phrases += "Need... food..."
- phrases += "Must... eat..."
- else if(nutrition < get_hunger_nutrition())
- phrases += "Hungry..."
- phrases += "Where is the food?"
- phrases += "I want to eat..."
- phrases += "Rawr..."
- phrases += "Blop..."
- phrases += "Blorble..."
- if(rabid || attacked)
- phrases += "Hrr..."
- phrases += "Nhuu..."
- phrases += "Unn..."
- if(mood == ":3")
- phrases += "Purr..."
- if(attacked)
- phrases += "Grrr..."
- if(getToxLoss() > 30)
- phrases += "Cold..."
- if(getToxLoss() > 60)
- phrases += "So... cold..."
- phrases += "Very... cold..."
- if(getToxLoss() > 90)
- phrases += "..."
- phrases += "C... c..."
- if(Victim)
- phrases += "Nom..."
- phrases += "Tasty..."
- if(powerlevel > 3) phrases += "Bzzz..."
- if(powerlevel > 5) phrases += "Zap..."
- if(powerlevel > 8) phrases += "Zap... Bzz..."
- if(mood == "sad") phrases += "Bored..."
- if(slimes_near) phrases += "Brother..."
- if(slimes_near > 1) phrases += "Brothers..."
- if(dead_slimes) phrases += "What happened?"
- if(!slimes_near)
- phrases += "Lonely..."
- for(var/M in friends_near)
- phrases += "[M]... friend..."
- if(nutrition < get_hunger_nutrition())
- phrases += "[M]... feed me..."
- say (pick(phrases))
-
-/mob/living/carbon/slime/proc/get_max_nutrition() // Can't go above it
- if(is_adult) return 1200
- else return 1000
-
-/mob/living/carbon/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat
- if(is_adult) return 1000
- else return 800
-
-/mob/living/carbon/slime/proc/get_hunger_nutrition() // Below it we will always eat
- if(is_adult) return 600
- else return 500
-
-/mob/living/carbon/slime/proc/get_starve_nutrition() // Below it we will eat before everything else
- if(is_adult) return 300
- else return 200
-
-/mob/living/carbon/slime/proc/will_hunt(hunger = -1) // Check for being stopped from feeding and chasing
- if(docile)
- return 0
- if(hunger == 2 || rabid || attacked)
- return 1
- if(Leader)
- return 0
- if(holding_still)
- return 0
- return 1
diff --git a/code/modules/mob/living/carbon/slime/powers.dm b/code/modules/mob/living/carbon/slime/powers.dm
deleted file mode 100644
index 40f9060ee63..00000000000
--- a/code/modules/mob/living/carbon/slime/powers.dm
+++ /dev/null
@@ -1,233 +0,0 @@
-/mob/living/carbon/slime/verb/Feed()
- set category = "Slime"
- set desc = "This will let you feed on any valid creature in the surrounding area. This should also be used to halt the feeding process."
- if(Victim)
- Feedstop()
- return 0
-
- if(docile)
- to_chat(src, "I'm not hungry anymore...")
- return 0
-
- if(stat)
- to_chat(src, "I must be conscious to do this...")
- return 0
-
- var/list/choices = list()
- for(var/mob/living/C in view(1,src))
- if(C!=src && !istype(C,/mob/living/carbon/slime) && Adjacent(C))
- choices += C
-
- var/mob/living/M = input(src,"Who do you wish to feed on?") in null|choices
- if(!M)
- return 0
- if(Adjacent(M))
- if(isbrain(M))
- to_chat(src, "This subject does not have an edible life energy...")
- return 0
-
- if(iscarbon(M) && (M.health < -70))
- to_chat(src, "This subject does not have a strong enough life energy...")
- return 0
-
- if(isanimal(M) && (M.health < 1))//animals don't go into crit, stupid; fixes infinite energy exploit
- to_chat(src, "This subject does not have a strong enough life energy...")
- return 0
-
- for(var/mob/living/carbon/slime/met in view())
- if(met.Victim == M && met != src)
- to_chat(src, "The [met.name] is already feeding on this subject...")
- return 0
-
- to_chat(src, "I have latched onto the subject and begun feeding...")
- to_chat(M, "The [name] has latched onto your head!")
-
- Feedon(M)
- return 1
-
-/mob/living/carbon/slime/proc/Feedon(var/mob/living/M)
- Victim = M
- forceMove(M.loc)
- canmove = 0
- anchored = 1
- var/lastnut = nutrition
- var/fed_succesfully = 0
- var/health_minimum = -70
- if(is_adult)
- icon_state = "[colour] adult slime eat"
- else
- icon_state = "[colour] baby slime eat"
-
- if(isanimal(Victim))
- health_minimum = 0
- while(Victim && Victim.health > health_minimum && stat != DEAD)
- canmove = 0
-
- if(Adjacent(Victim))
- forceMove(M.loc)
-
- if(iscarbon(Victim))
- Victim.adjustCloneLoss(rand(5,6))
- Victim.adjustToxLoss(rand(1,2))
- if(Victim.health <= 0)
- Victim.adjustToxLoss(rand(2,4))
-
- if(prob(15) && Victim.client)
- to_chat(Victim, "[pick("You can feel your body becoming weak!", \
- "You feel like you're about to die!", \
- "You feel every part of your body screaming in agony!", \
- "A low, rolling pain passes through your body!", \
- "Your body feels as if it's falling apart!", \
- "You feel extremely weak!", \
- "A sharp, deep pain bathes every inch of your body!")]")
-
- fed_succesfully = 1
-
- else if(health_minimum == 0) //we already know it's a simple_animal from above
- Victim.adjustBruteLoss(is_adult ? rand(7, 15) : rand(4, 12))
- fed_succesfully = 1
-
- else
- to_chat(src, "[pick("This subject is incompatable", \
- "This subject does not have a life energy", "This subject is empty", \
- "I am not satisified", "I can not feed from this subject", \
- "I do not feel nourished", "This subject is not food")]...")
-
- if(fed_succesfully)
- add_nutrition(rand(15,30), lastnut)
-
- //Heal yourself.
- adjustOxyLoss(-10)
- adjustBruteLoss(-10)
- adjustFireLoss(-10)
- adjustCloneLoss(-10)
-
- updatehealth("slime feeding")
- if(Victim)
- Victim.updatehealth("slime feeding")
-
- sleep(rand(15,45))
-
- else
- break
-
- if(stat == 2)
- if(!is_adult)
- icon_state = "[colour] baby slime dead"
-
- else
- if(is_adult)
- icon_state = "[colour] adult slime"
- else
- icon_state = "[colour] baby slime"
-
- canmove = 1
- anchored = 0
-
- if(M)
- if(M.health <= health_minimum)
- M.canmove = 0
- if(!client)
- if(Victim && !rabid && !attacked)
- if(Victim.LAssailant && Victim.LAssailant != Victim)
- if(prob(50))
- if(!(Victim.LAssailant in Friends))
- Friends[Victim.LAssailant] = 1
- //Friends.Add(Victim.LAssailant) // no idea why i was using the |= operator
- else
- ++Friends[Victim.LAssailant]
-
-
- if(M.client && istype(src, /mob/living/carbon/human))
- if(prob(85))
- rabid = 1 // UUUNNBGHHHH GONNA EAT JUUUUUU
-
- if(client)
- to_chat(src, "This subject does not have a strong enough life energy anymore...")
- else
- M.canmove = 1
- if(client)
- to_chat(src, "I have stopped feeding...")
- else
- if(client)
- to_chat(src, "I have stopped feeding...")
-
- Victim = null
-
-/mob/living/carbon/slime/proc/Feedstop()
- if(Victim)
- if(Victim.client)
- to_chat(Victim, "[src] has let go of your head!")
- Victim = null
-
-/mob/living/carbon/slime/proc/UpdateFeed(var/mob/M)
- if(Victim)
- if(Victim == M)
- forceMove(M.loc) // simple "attach to head" effect!
-
-
-/mob/living/carbon/slime/verb/Evolve()
- set category = "Slime"
- set desc = "This will let you evolve from baby to adult slime."
-
- if(stat)
- to_chat(src, "I must be conscious to do this...")
- return
- if(!is_adult)
- if(amount_grown >= 10)
- is_adult = 1
- maxHealth = 200
- amount_grown = 0
- regenerate_icons()
- name = text("[colour] [is_adult ? "adult" : "baby"] slime ([number])")
- else
- to_chat(src, "I am not ready to evolve yet...")
- else
- to_chat(src, "I have already evolved...")
-
-/mob/living/carbon/slime/verb/Reproduce()
- set category = "Slime"
- set desc = "This will make you split into four Slimes."
-
- if(stat)
- to_chat(src, "I must be conscious to do this...")
- return
-
- if(is_adult)
- if(amount_grown >= 10)
- if(stat)
- to_chat(src, "I must be conscious to do this...")
- return
-
- var/list/babies = list()
- var/new_nutrition = round(nutrition * 0.9)
- var/new_powerlevel = round(powerlevel / 4)
- for(var/i=1,i<=4,i++)
- var/mob/living/carbon/slime/M = new /mob/living/carbon/slime/(loc)
- if(mutation_chance >= 100)
- M.colour = "rainbow"
- else if(prob(mutation_chance))
- M.colour = slime_mutation[rand(1,4)]
- else
- M.colour = colour
- if(ckey)
- M.nutrition = new_nutrition //Player slimes are more robust at spliting. Once an oversight of poor copypasta, now a feature!
- M.powerlevel = new_powerlevel
- if(i != 1)
- step_away(M,src)
- M.Friends = Friends.Copy()
- babies += M
- M.mutation_chance = Clamp(mutation_chance+(rand(5,-5)),0,100)
- feedback_add_details("slime_babies_born","slimebirth_[replacetext(M.colour," ","_")]")
-
- var/mob/living/carbon/slime/new_slime = pick(babies)
- new_slime.universal_speak = universal_speak
- if(src.mind)
- src.mind.transfer_to(new_slime)
- else
- new_slime.key = src.key
- qdel(src)
- else
- to_chat(src, "I am not ready to reproduce yet...")
- else
- to_chat(src, "I am not old enough to reproduce yet...")
diff --git a/code/modules/mob/living/carbon/slime/say.dm b/code/modules/mob/living/carbon/slime/say.dm
deleted file mode 100644
index 2096da01360..00000000000
--- a/code/modules/mob/living/carbon/slime/say.dm
+++ /dev/null
@@ -1,29 +0,0 @@
-/mob/living/carbon/slime/say_quote(var/text, var/datum/language/speaking)
- var/verb = "telepathically chirps"
- var/ending = copytext(text, length(text))
-
- if(ending == "?")
- verb = "telepathically asks"
- else if(ending == "!")
- verb = "telepathically cries"
-
- return verb
-
-/mob/living/carbon/slime/say_understands(var/other)
- if(istype(other, /mob/living/carbon/slime))
- return 1
- return ..()
-
-/mob/living/carbon/slime/hear_say(list/message_pieces, var/verb = "says", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
- if(speaker in Friends)
- speech_buffer = list()
- speech_buffer.Add(speaker)
- speech_buffer.Add(lowertext(html_decode(multilingual_to_message(message_pieces))))
- ..()
-
-/mob/living/carbon/slime/hear_radio(list/message_pieces, var/verb="says", var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="", var/atom/follow_target)
- if(speaker in Friends)
- speech_buffer = list()
- speech_buffer.Add(speaker)
- speech_buffer.Add(lowertext(html_decode(multilingual_to_message(message_pieces))))
- ..()
diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm
deleted file mode 100644
index 727b12a9e34..00000000000
--- a/code/modules/mob/living/carbon/slime/slime.dm
+++ /dev/null
@@ -1,545 +0,0 @@
-/mob/living/carbon/slime
- name = "baby slime"
- icon = 'icons/mob/slimes.dmi'
- icon_state = "grey baby slime"
- pass_flags = PASSTABLE
- ventcrawler = 2
- speak_emote = list("telepathically chirps")
- layer = 5
- maxHealth = 150
- health = 150
- gender = NEUTER
- nutrition = 700
- see_in_dark = 8
- update_slimes = 0
- faction = list("slime","neutral")
- // canstun and canweaken don't affect slimes because they ignore stun and weakened variables
- // for the sake of cleanliness, though, here they are.
- status_flags = CANPARALYSE|CANPUSH
-
- var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside
- var/mutation_chance = 30 // Chance of mutating, should be between 25 and 35
-
- var/powerlevel = 0 // 1-10 controls how much electricity they are generating
- var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces
-
- var/number = 0 // Used to understand when someone is talking to it
-
- var/mob/living/Victim = null // the person the slime is currently feeding on
- var/mob/living/Target = null // AI variable - tells the slime to hunt this down
- var/mob/living/Leader = null // AI variable - tells the slime to follow this person
-
- var/attacked = 0 // Determines if it's been attacked recently. Can be any number, is a cooloff-ish variable
- var/rabid = 0 // If set to 1, the slime will attack and eat anything it comes in contact with
- var/holding_still = 0 // AI variable, cooloff-ish for how long it's going to stay in one place
- var/target_patience = 0 // AI variable, cooloff-ish for how long it's going to follow its target
-
- var/list/Friends = list() // A list of friends; they are not considered targets for feeding; passed down after splitting
-
- var/list/speech_buffer = list() // Last phrase said near it and person who said it
-
- var/mood = "" // To show its face
- var/is_adult = 0
- var/docile = 0
- var/core_removal_stage = 0 //For removing cores.
- var/mutator_used = FALSE //So you can't shove a dozen mutators into a single slime
-
- ///////////TIME FOR SUBSPECIES
-
- var/colour = "grey"
- var/coretype = /obj/item/slime_extract/grey
- var/list/slime_mutation[4]
-
-/mob/living/carbon/slime/New()
- create_reagents(100)
- spawn (0)
- number = rand(1, 1000)
- name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
- icon_state = "[colour] [is_adult ? "adult" : "baby"] slime"
- real_name = name
- slime_mutation = mutation_table(colour)
- var/sanitizedcolour = replacetext(colour, " ", "")
- coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]")
- ..()
-
-/mob/living/carbon/slime/random/New()
- colour = pick("grey","orange", "metal", "blue", "purple", "dark purple", "dark blue", "green", "silver", "yellow", "gold", "yellow", "red", "silver", "pink", "cerulean", "sepia", "bluespace", "pyrite", "light pink", "oil", "adamantine", "black")
- ..()
-
-/mob/living/carbon/slime/Destroy()
- for(var/obj/machinery/computer/camera_advanced/xenobio/X in GLOB.machines)
- if(src in X.stored_slimes)
- X.stored_slimes -= src
- return ..()
-
-/mob/living/carbon/slime/can_unbuckle()
- return FALSE
-
-/mob/living/carbon/slime/can_buckle()
- return FALSE
-
-/mob/living/carbon/slime/get_mob_buckling_height(mob/seat)
- if(..())
- return 3
-
-/mob/living/carbon/slime/regenerate_icons()
- icon_state = "[colour] [is_adult ? "adult" : "baby"] slime"
- overlays.len = 0
- if(mood)
- overlays += image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]")
- ..()
-
-/mob/living/carbon/slime/movement_delay()
- if(bodytemperature >= 330.23) // 135 F
- return -1 // slimes become supercharged at high temperatures
-
- . = ..()
-
- var/health_deficiency = (100 - health)
- if(health_deficiency >= 45)
- . += (health_deficiency / 25)
-
- if(bodytemperature < 183.222)
- . += (283.222 - bodytemperature) / 10 * 1.75
-
- if(reagents)
- if(reagents.has_reagent("methamphetamine")) // Meth slows slimes down
- . *= 2
-
- if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow
- . *= 5
-
- if(health <= 0) // if damaged, the slime moves twice as slow
- . *= 2
-
- . += config.slime_delay
-
-/mob/living/carbon/slime/ObjBump(obj/O)
- if(!client && powerlevel > 0)
- var/chance = 10
- switch(powerlevel)
- if(1 to 2) chance = 20
- if(3 to 4) chance = 30
- if(5 to 6) chance = 40
- if(7 to 8) chance = 60
- if(9) chance = 70
- if(10) chance = 95
- if(prob(chance))
- if(istype(O, /obj/structure/window) || istype(O, /obj/structure/grille))
- if(nutrition <= get_hunger_nutrition() && !Atkcool)
- if(is_adult || prob(5))
- O.attack_slime(src)
- Atkcool = 1
- spawn(45)
- Atkcool = 0
-
-/mob/living/carbon/slime/Process_Spacemove(var/movement_dir = 0)
- return 2
-
-/mob/living/carbon/slime/Stat()
- ..()
-
- statpanel("Status")
- if(is_adult)
- stat(null, "Health: [round((health / 200) * 100)]%")
- else
- stat(null, "Health: [round((health / 150) * 100)]%")
-
- if(client.statpanel == "Status")
- if(!docile)
- stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]")
- if(amount_grown >= 10)
- if(is_adult)
- stat(null, "You can reproduce!")
- else
- stat(null, "You can evolve!")
-
- stat(null,"Power Level: [powerlevel]")
-
-/mob/living/carbon/slime/updatehealth(reason)
- . = ..()
- update_health_hud()
-
-/mob/living/carbon/slime/update_health_hud()
- if(hud_used)
- var/severity = 0
- var/healthpercent = (health/maxHealth) * 100
- if(stat != DEAD)
- switch(healthpercent)
- if(100 to INFINITY)
- healths.icon_state = "slime_health0"
- if(80 to 100)
- healths.icon_state = "slime_health1"
- severity = 1
- if(60 to 80)
- healths.icon_state = "slime_health2"
- severity = 2
- if(40 to 60)
- healths.icon_state = "slime_health3"
- severity = 3
- if(20 to 40)
- healths.icon_state = "slime_health4"
- severity = 4
- if(0 to 20)
- healths.icon_state = "slime_health5"
- severity = 5
- if(-199 to 0)
- healths.icon_state = "slime_health6"
- severity = 6
- else
- healths.icon_state = "slime_health7"
- severity = 6
- if(severity > 0)
- overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
- else
- clear_fullscreen("brute")
-
-/mob/living/carbon/slime/adjustFireLoss(amount)
- ..(-abs(amount)) // Heals them
- return
-
-/mob/living/carbon/slime/bullet_act(var/obj/item/projectile/Proj)
- attacked += 10
- ..(Proj)
- return 0
-
-/mob/living/carbon/slime/emp_act(severity)
- powerlevel = 0 // oh no, the power!
- ..()
-
-/mob/living/carbon/slime/ex_act(severity)
- ..()
-
- var/b_loss = null
- var/f_loss = null
- switch(severity)
- if(1.0)
- qdel(src)
- return
-
- if(2.0)
-
- b_loss += 60
- f_loss += 60
-
-
- if(3.0)
- b_loss += 30
-
- adjustBruteLoss(b_loss)
- adjustFireLoss(f_loss)
-
- updatehealth()
-
-
-/mob/living/carbon/slime/blob_act(obj/structure/blob/B)
- show_message(" The blob attacks you!")
- adjustBruteLoss(20)
- updatehealth()
-
-/mob/living/carbon/slime/MouseDrop(atom/movable/A)
- if(isliving(A) && A != src && usr == src)
- var/mob/living/Food = A
- if(Food.Adjacent(src) && !stat && Food.stat != DEAD) //messy
- Feedon(Food)
- ..()
-
-/mob/living/carbon/slime/unEquip(obj/item/W as obj, force)
- return
-
-/mob/living/carbon/slime/attack_ui(slot)
- return
-
-/mob/living/carbon/slime/attack_slime(mob/living/carbon/slime/M)
- ..()
- if(Victim)
- Victim = null
- visible_message("[M] pulls [src] off!")
- return
- attacked += 5
- if(nutrition >= 100) //steal some nutrition. negval handled in life()
- nutrition -= (50 + (5 * M.amount_grown))
- M.add_nutrition(50 + (5 * M.amount_grown))
- if(health > 0)
- adjustBruteLoss(4 + (2 * M.amount_grown)) //amt_grown isn't very linear but it works
- updatehealth()
- M.adjustBruteLoss(-4 + (-2 * M.amount_grown))
- M.updatehealth()
-
-/mob/living/carbon/slime/attack_animal(mob/living/simple_animal/M)
- . = ..()
- if(.)
- var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
- attacked += 10
- adjustBruteLoss(damage)
- updatehealth()
-
-/mob/living/carbon/slime/attack_larva(mob/living/carbon/alien/larva/L)
- if(..()) //successful larva bite.
- var/damage = rand(1, 3)
- if(stat != DEAD)
- L.amount_grown = min(L.amount_grown + damage, L.max_grown)
- adjustBruteLoss(damage)
- updatehealth()
-
-/mob/living/carbon/slime/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
- if(user.a_intent == INTENT_HARM)
- if(Victim || Target)
- Victim = null
- Target = null
- anchored = 0
- if(prob(80) && !client)
- Discipline++
- spawn(0)
- step_away(src, user, 15)
- sleep(3)
- step_away(src, user, 15)
- ..(user, TRUE)
- playsound(loc, "punch", 25, 1, -1)
- visible_message("[user] has punched [src]!", "[user] has punched [src]!")
- adjustBruteLoss(15)
- return TRUE
-
-/mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M)
- if(Victim)
- M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
- if(Victim == M)
- if(prob(60))
- visible_message("[M] attempts to wrestle \the [name] off!")
- playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
-
- else
- visible_message(" [M] manages to wrestle \the [name] off!")
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
-
- if(prob(90) && !client)
- Discipline++
-
- SStun = 1
- spawn(rand(45,60))
- SStun = 0
-
- Victim = null
- anchored = 0
- step_away(src,M)
-
- return
-
- else
- if(prob(30))
- visible_message("[M] attempts to wrestle \the [name] off of [Victim]!")
- playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
-
- else
- visible_message(" [M] manages to wrestle \the [name] off of [Victim]!")
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
-
- if(prob(80) && !client)
- Discipline++
-
- if(!is_adult)
- if(Discipline == 1)
- attacked = 0
-
- SStun = 1
- spawn(rand(55,65))
- SStun = 0
-
- Victim = null
- anchored = 0
- step_away(src,M)
-
- return
-
- if(..()) //To allow surgery to return properly.
- return
-
- switch(M.a_intent)
-
- if(INTENT_HELP)
- help_shake_act(M)
-
- if(INTENT_GRAB)
- grabbedby(M)
-
- else
- M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
- var/damage = rand(1, 9)
- attacked += 10
- if(prob(90))
- playsound(loc, "punch", 25, 1, -1)
- add_attack_logs(M, src, "Melee attacked with fists")
- visible_message("[M] has punched [src]!", \
- "[M] has punched [src]!")
- if(stat != DEAD)
- adjustBruteLoss(damage)
- updatehealth()
- else
- playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
- visible_message("[M] has attempted to punch [src]!")
- return
-
-/mob/living/carbon/slime/attack_alien(mob/living/carbon/alien/humanoid/M)
- if(..()) //if harm or disarm intent.
- if(M.a_intent == INTENT_HARM)
- if(prob(95))
- attacked += 10
- playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
- var/damage = rand(15, 30)
- if(damage >= 25)
- damage = rand(20, 40)
- visible_message("[M] has slashed [name]!", \
- "[M] has slashed [name]!")
- else
- visible_message("[M] has wounded [name]!", \
- ")[M] has wounded [name]!")
- add_attack_logs(M, src, "Alien attacked")
- if(stat != DEAD)
- adjustBruteLoss(damage)
- updatehealth()
- else
- playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
- visible_message("[M] has attempted to lunge at [name]!", \
- "[M] has attempted to lunge at [name]!")
-
- if(M.a_intent == INTENT_DISARM)
- playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
- var/damage = 5
- attacked += 10
-
- if(prob(95))
- visible_message("[M] has tackled [name]!", \
- "[M] has tackled [name]!")
-
- if(Victim || Target)
- Victim = null
- Target = null
- anchored = 0
- if(prob(80) && !client)
- Discipline++
- if(!isslime(src))
- if(Discipline == 1)
- attacked = 0
-
- SStun = 1
- spawn(rand(5,20))
- SStun = 0
-
- spawn(0)
-
- step_away(src,M,15)
- sleep(3)
- step_away(src,M,15)
-
- else
- drop_item()
- visible_message("[M] has disarmed [name]!",
- "[M] has disarmed [name]!")
- add_attack_logs(M, src, "Alien disarmed")
- adjustBruteLoss(damage)
- updatehealth()
- return
-
-/mob/living/carbon/slime/attackby(obj/item/W, mob/living/user, params)
- if(istype(W,/obj/item/stack/sheet/mineral/plasma)) //Lets you feed slimes plasma.
- if(user in Friends)
- ++Friends[user]
- else
- Friends[user] = 1
- to_chat(user, "You feed the slime the plasma. It chirps happily.")
- var/obj/item/stack/sheet/mineral/plasma/S = W
- S.use(1)
- return
- else if(W.force > 0)
- attacked += 10
- if(prob(25))
- user.do_attack_animation(src)
- to_chat(user, "[W] passes right through [src]!")
- return
- if(Discipline && prob(50)) // wow, buddy, why am I getting attacked??
- Discipline = 0
- else if(W.force >= 3)
- if(is_adult)
- if(prob(5 + round(W.force/2)))
- if(Victim || Target)
- if(prob(80) && !client)
- Discipline++
-
- Victim = null
- Target = null
- anchored = 0
-
- SStun = 1
- spawn(rand(5,20))
- SStun = 0
-
- spawn(0)
- if(user)
- canmove = 0
- step_away(src, user)
- if(prob(25 + W.force))
- sleep(2)
- if(user)
- step_away(src, user)
- canmove = 1
-
- else
- if(prob(10 + W.force*2))
- if(Victim || Target)
- if(prob(80) && !client)
- Discipline++
- if(Discipline == 1)
- attacked = 0
- SStun = 1
- spawn(rand(5,20))
- SStun = 0
-
- Victim = null
- Target = null
- anchored = 0
-
- spawn(0)
- if(user)
- canmove = 0
- step_away(src, user)
- if(prob(25 + W.force*4))
- sleep(2)
- if(user)
- step_away(src, user)
- canmove = 1
- ..()
-
-/mob/living/carbon/slime/restrained()
- return 0
-
-mob/living/carbon/slime/var/temperature_resistance = T0C+75
-
-/mob/living/carbon/slime/show_inv(mob/user)
- return
-
-/mob/living/carbon/slime/toggle_throw_mode()
- return
-
-/mob/living/carbon/slime/water_act(volume, temperature, source, method = TOUCH)
- . = ..()
-
- var/water_damage = rand(10, 15) * volume
- adjustToxLoss(water_damage)
-
- if(!client && Target && volume >= 3)
- Target = null
- ++Discipline
-
-/mob/living/carbon/slime/can_use_vents()
- if(Victim)
- return "You cannot ventcrawl while feeding."
- ..()
-
-/mob/living/carbon/slime/forceFed(var/obj/item/reagent_containers/food/toEat, mob/user, fullness)
- if(istype(toEat, /obj/item/reagent_containers/food/drinks))
- return 1
- to_chat(user, "This creature does not seem to have a mouth!")
- return 0
-
-/mob/living/carbon/slime/can_hear()
- . = TRUE //honestly fuck slimes and organ bullshit
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/slime/update_icons.dm b/code/modules/mob/living/carbon/slime/update_icons.dm
deleted file mode 100644
index 2310f32a76e..00000000000
--- a/code/modules/mob/living/carbon/slime/update_icons.dm
+++ /dev/null
@@ -1 +0,0 @@
-//no special icon processing
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index f16ade7791f..e510cf828f8 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -431,7 +431,7 @@
radiation = 0
SetDruggy(0)
SetHallucinate(0)
- nutrition = NUTRITION_LEVEL_FED + 50
+ set_nutrition(NUTRITION_LEVEL_FED + 50)
bodytemperature = 310
CureBlind()
CureNearsighted()
@@ -545,10 +545,6 @@
if(s_active && !(s_active in contents) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
s_active.close(src)
- if(update_slimes)
- for(var/mob/living/carbon/slime/M in view(1,src))
- M.UpdateFeed(src)
-
/mob/living/proc/handle_footstep(turf/T)
if(istype(T))
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 8cfbd2be4d1..44e2761708e 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -278,33 +278,21 @@
return G
-/mob/living/attack_slime(mob/living/carbon/slime/M)
+/mob/living/attack_slime(mob/living/simple_animal/slime/M)
if(!SSticker)
to_chat(M, "You cannot attack people before the game has started.")
return
- if(M.Victim)
+ if(M.buckled)
+ if(M in buckled_mobs)
+ M.Feedstop()
return // can't attack while eating!
if(stat != DEAD)
+ add_attack_logs(src, M, "Slime'd")
M.do_attack_animation(src)
- visible_message("The [M.name] glomps [src]!", \
- "The [M.name] glomps [src]!")
-
- if(M.powerlevel > 0)
- var/stunprob = M.powerlevel * 7 + 10 // 17 at level 1, 80 at level 10
- if(prob(stunprob))
- M.powerlevel -= 3
- if(M.powerlevel < 0)
- M.powerlevel = 0
-
- visible_message("The [M.name] has shocked [src]!", \
- "The [M.name] has shocked [src]!")
-
- do_sparks(5, 1, src)
- return 1
- add_attack_logs(src, M, "Slime'd")
- return
+ visible_message("\The [M.name] glomps [src]!", "\The [M.name] glomps you!")
+ return TRUE
/mob/living/attack_animal(mob/living/simple_animal/M)
M.face_atom(src)
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 1e3343f90f7..5bc42caab14 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -28,7 +28,6 @@
var/on_fire = 0 //The "Are we on fire?" var
var/fire_stacks = 0 //Tracks how many stacks of fire we have on, max is usually 20
- var/update_slimes = 1
var/implanting = 0 //Used for the mind-slave implant
var/floating = 0
var/mob_size = MOB_SIZE_HUMAN
diff --git a/code/modules/mob/living/silicon/ai/ai_defense.dm b/code/modules/mob/living/silicon/ai/ai_defense.dm
index c8ffebc6647..702b745e4fc 100644
--- a/code/modules/mob/living/silicon/ai/ai_defense.dm
+++ b/code/modules/mob/living/silicon/ai/ai_defense.dm
@@ -4,5 +4,5 @@
return
..()
-/mob/living/silicon/ai/attack_slime(mob/living/carbon/slime/user)
+/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user)
return //immune to slimes
diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm
index c519ba0846a..1b8a4fa43c3 100644
--- a/code/modules/mob/living/silicon/ai/examine.dm
+++ b/code/modules/mob/living/silicon/ai/examine.dm
@@ -1,9 +1,5 @@
/mob/living/silicon/ai/examine(mob/user)
- to_chat(user, "*---------*")
- if(!..(user))
- to_chat(user, "*---------*")
- return
-
+ . = ..()
var/msg = ""
if(src.stat == DEAD)
msg += "It appears to be powered-down.\n"
@@ -26,7 +22,7 @@
msg += ""
msg += "*---------*"
- to_chat(user, msg)
+ . += msg
user.showLaws(src)
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index d2e52c39197..cb6b3eaa104 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -525,8 +525,7 @@
density = 0 //this is reset every canmove update otherwise
/mob/living/silicon/pai/examine(mob/user)
- to_chat(user, "*---------*")
- ..(user)
+ . = ..()
var/msg = ""
@@ -544,7 +543,7 @@
msg += "\nIt is [pose]"
msg += "\n*---------*"
- to_chat(user, msg)
+ . += msg
/mob/living/silicon/pai/bullet_act(var/obj/item/projectile/Proj)
..(Proj)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index 0f3422f237a..edf53f56918 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -13,7 +13,7 @@
braintype = "Robot"
lawupdate = 0
density = 0
- req_access = list(access_engine, access_robotics)
+ req_one_access = list(access_engine, access_robotics)
ventcrawler = 2
magpulse = 1
mob_size = MOB_SIZE_SMALL
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
index 35bbad68b6a..50463b17bec 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
@@ -46,9 +46,9 @@
visible_message("\The [src] voices a strident beep, indicating a drone chassis is prepared.")
/obj/machinery/drone_fabricator/examine(mob/user)
- ..(user)
+ . = ..()
if(produce_drones && drone_progress >= 100 && istype(user,/mob/dead) && config.allow_drone_spawn && count_drones() < config.max_maint_drones)
- to_chat(user, "
A drone is prepared. Select 'Join As Drone' from the Ghost tab to spawn as a maintenance drone.")
+ . += "
A drone is prepared. Select 'Join As Drone' from the Ghost tab to spawn as a maintenance drone."
/obj/machinery/drone_fabricator/proc/count_drones()
var/drones = 0
diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm
index 98b540347ac..56d01fea839 100644
--- a/code/modules/mob/living/silicon/robot/examine.dm
+++ b/code/modules/mob/living/silicon/robot/examine.dm
@@ -1,6 +1,5 @@
/mob/living/silicon/robot/examine(mob/user)
- to_chat(user, "*---------*")
- ..(user)
+ . = ..()
var/msg = ""
if(module)
@@ -55,5 +54,5 @@
pose = addtext(pose,".") //Makes sure all emotes end with a period.
msg += "\nIt is [pose]"
- to_chat(user, msg)
+ . += msg
user.showLaws(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index f3e8ceefad7..0ebfc5920d3 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -65,7 +65,8 @@ var/list/robot_verbs_default = list(
var/wiresexposed = 0
var/locked = 1
- var/list/req_access = list(access_robotics)
+ var/list/req_one_access = list(access_robotics)
+ var/list/req_access
var/ident = 0
//var/list/laws = list()
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list())
@@ -889,6 +890,7 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/allowed(obj/item/I)
var/obj/dummy = new /obj(null) // Create a dummy object to check access on as to avoid having to snowflake check_access on every mob
dummy.req_access = req_access
+ dummy.req_one_access = req_one_access
if(dummy.check_access(I))
qdel(dummy)
@@ -1300,7 +1302,7 @@ var/list/robot_verbs_default = list(
designation = "SpecOps"
lawupdate = 0
scrambledcodes = 1
- req_access = list(access_cent_specops)
+ req_one_access = list(access_cent_specops)
ionpulse = 1
magpulse = 1
pdahide = 1
@@ -1350,7 +1352,7 @@ var/list/robot_verbs_default = list(
designation = "ERT"
lawupdate = 0
scrambledcodes = 1
- req_access = list(access_cent_specops)
+ req_one_access = list(access_cent_specops)
ionpulse = 1
force_modules = list("Engineering", "Medical", "Security")
diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm
index 85cc2ad5786..9b4f1089f46 100644
--- a/code/modules/mob/living/silicon/robot/robot_defense.dm
+++ b/code/modules/mob/living/silicon/robot/robot_defense.dm
@@ -19,7 +19,7 @@
..()
return
-/mob/living/silicon/robot/attack_slime(mob/living/carbon/slime/M)
+/mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M)
if(..()) //successful slime shock
flash_eyes(affect_silicon = 1)
var/stunprob = M.powerlevel * 7 + 10
diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm
index 119eb1b29c0..d827bf03692 100644
--- a/code/modules/mob/living/simple_animal/animal_defense.dm
+++ b/code/modules/mob/living/simple_animal/animal_defense.dm
@@ -58,12 +58,12 @@
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
return attack_threshold_check(damage, M.melee_damage_type)
-/mob/living/simple_animal/attack_slime(mob/living/carbon/slime/M)
- ..()
- var/damage = rand(15, 25)
- if(M.is_adult)
- damage = rand(20, 35)
- attack_threshold_check(damage)
+/mob/living/simple_animal/attack_slime(mob/living/simple_animal/slime/M)
+ if(..()) //successful slime attack
+ var/damage = rand(15, 25)
+ if(M.is_adult)
+ damage = rand(20, 35)
+ return attack_threshold_check(damage)
/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE, armorcheck = "melee")
var/temp_damage = damage
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 76f88220eda..1fba341fd59 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -232,14 +232,14 @@
to_chat(user, "You need to open maintenance panel first!")
/mob/living/simple_animal/bot/examine(mob/user)
- ..()
+ . = ..()
if(health < maxHealth)
if(health > maxHealth/3)
- to_chat(user, "[src]'s parts look loose.")
+ . += "[src]'s parts look loose."
else
- to_chat(user, "[src]'s parts look very loose!")
+ . += "[src]'s parts look very loose!"
else
- to_chat(user, "[src] is in pristine condition.")
+ . += "[src] is in pristine condition."
/mob/living/simple_animal/bot/adjustHealth(amount, updating_health = TRUE)
if(amount > 0 && prob(10))
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 218693b7dc3..35fde25b202 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -48,8 +48,7 @@
updateglow()
/mob/living/simple_animal/hostile/construct/examine(mob/user)
- to_chat(user, "*---------*")
- ..(user)
+ . = ..()
var/msg = ""
if(src.health < src.maxHealth)
@@ -61,7 +60,7 @@
msg += ""
msg += "*---------*"
- to_chat(user, msg)
+ . += msg
/mob/living/simple_animal/hostile/construct/attack_animal(mob/living/simple_animal/M)
if(istype(M, /mob/living/simple_animal/hostile/construct/builder))
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 5da6bee438d..3ca0c840efd 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -179,7 +179,7 @@
minbodytemp = 0
gold_core_spawnable = NO_SPAWN
var/cycles_alive = 0
- var/cycles_limit = 30
+ var/cycles_limit = 60
var/has_burst = FALSE
/mob/living/simple_animal/mouse/blobinfected/Life()
diff --git a/code/modules/mob/living/simple_animal/friendly/slime.dm b/code/modules/mob/living/simple_animal/friendly/slime.dm
deleted file mode 100644
index b4135bdf764..00000000000
--- a/code/modules/mob/living/simple_animal/friendly/slime.dm
+++ /dev/null
@@ -1,60 +0,0 @@
-/mob/living/simple_animal/slime
- name = "pet slime"
- desc = "A lovable, domesticated slime."
- icon = 'icons/mob/slimes.dmi'
- icon_state = "grey baby slime"
- icon_living = "grey baby slime"
- icon_dead = "grey baby slime dead"
- speak_emote = list("chirps")
- health = 100
- maxHealth = 100
- response_help = "pets"
- response_disarm = "shoos"
- response_harm = "stomps on"
- emote_see = list("jiggles", "bounces in place")
- pass_flags = PASSTABLE
- var/colour = "grey"
-
-/mob/living/simple_animal/slime/adult
- health = 200
- maxHealth = 200
- icon_state = "grey adult slime"
- icon_living = "grey adult slime"
-
-/mob/living/simple_animal/slime/New()
- ..()
- overlays += "aslime-:33"
-
-/mob/living/simple_animal/slime/updatehealth(reason)
- . = ..()
- update_health_hud()
-
-/mob/living/simple_animal/slime/update_health_hud()
- if(hud_used)
- var/severity = 0
- var/healthpercent = (health/maxHealth) * 100
- switch(healthpercent)
- if(100 to INFINITY)
- healths.icon_state = "slime_health0"
- if(80 to 100)
- healths.icon_state = "slime_health1"
- severity = 1
- if(60 to 80)
- healths.icon_state = "slime_health2"
- severity = 2
- if(40 to 60)
- healths.icon_state = "slime_health3"
- severity = 3
- if(20 to 40)
- healths.icon_state = "slime_health4"
- severity = 4
- if(1 to 20)
- healths.icon_state = "slime_health5"
- severity = 5
- else
- healths.icon_state = "slime_health7"
- severity = 6
- if(severity > 0)
- overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
- else
- clear_fullscreen("brute")
diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm
index 540e4bbf28e..6349c50851d 100644
--- a/code/modules/mob/living/simple_animal/hostile/bees.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bees.dm
@@ -79,9 +79,9 @@
beehome = null
/mob/living/simple_animal/hostile/poison/bees/examine(mob/user)
- ..()
+ . = ..()
if(!bee_syndicate && !beehome)
- to_chat(user, "This bee is homeless!")
+ . += "This bee is homeless!"
/mob/living/simple_animal/hostile/poison/bees/proc/generate_bee_visuals()
overlays.Cut()
diff --git a/code/modules/mob/living/simple_animal/hostile/headslug.dm b/code/modules/mob/living/simple_animal/hostile/headslug.dm
index 99c11431695..d2329162da7 100644
--- a/code/modules/mob/living/simple_animal/hostile/headslug.dm
+++ b/code/modules/mob/living/simple_animal/hostile/headslug.dm
@@ -24,9 +24,9 @@
var/egg_lain = 0
/mob/living/simple_animal/hostile/headslug/examine(mob/user)
- ..()
+ . = ..()
if(stat == DEAD)
- to_chat(desc = "It appears to be dead.")
+ . += "It appears to be dead."
/mob/living/simple_animal/hostile/headslug/proc/Infect(mob/living/carbon/victim)
var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim)
diff --git a/code/modules/mob/living/simple_animal/hostile/hellhound.dm b/code/modules/mob/living/simple_animal/hostile/hellhound.dm
index 2f149fbf3ee..d83ca04d6c4 100644
--- a/code/modules/mob/living/simple_animal/hostile/hellhound.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hellhound.dm
@@ -72,7 +72,7 @@
msgs += "It is currently licking its wounds, regenerating the damage to its body!"
else
msgs += "It is currently resting."
- to_chat(usr,msgs.Join("
"))
+ . += msgs.Join("
")
/mob/living/simple_animal/hostile/hellhound/Life(seconds, times_fired)
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm
index 29739a9d867..3756fabf522 100644
--- a/code/modules/mob/living/simple_animal/hostile/illusion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm
@@ -40,9 +40,9 @@
/mob/living/simple_animal/hostile/illusion/examine(mob/user)
if(parent_mob)
- parent_mob.examine(user)
+ . = parent_mob.examine(user)
else
- return ..()
+ . = ..()
/mob/living/simple_animal/hostile/illusion/AttackingTarget()
diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm
index 9269b7dc12c..bf2090d44b9 100644
--- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm
@@ -36,11 +36,11 @@
var/image/cap_dead = null
/mob/living/simple_animal/hostile/mushroom/examine(mob/user)
- ..(user)
+ . = ..()
if(health >= maxHealth)
- to_chat(user, "It looks healthy.")
+ . += "It looks healthy."
else
- to_chat(user, "It looks like it's been roughed up.")
+ . += "It looks like it's been roughed up."
/mob/living/simple_animal/hostile/mushroom/Life(seconds, times_fired)
..()
diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
index 8f4ef5c7810..92c01d7d72b 100644
--- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -81,11 +81,11 @@
START_PROCESSING(SSprocessing, src)
/obj/structure/spawner/nether/examine(mob/user)
- ..()
+ . = ..()
if(isskeleton(user) || iszombie(user))
- to_chat(user, "A direct link to another dimension full of creatures very happy to see you. You can see your house from here!")
+ . += "A direct link to another dimension full of creatures very happy to see you. You can see your house from here!"
else
- to_chat(user, "A direct link to another dimension full of creatures not very happy to see you. Entering the link would be a very bad idea.")
+ . += "A direct link to another dimension full of creatures not very happy to see you. Entering the link would be a very bad idea."
/obj/structure/spawner/nether/attack_hand(mob/user)
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
index c9a0414fdf5..02d5ee5d14b 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
@@ -116,7 +116,9 @@
/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/Aggro()
. = ..()
- if(target && istype(depotarea))
+ if(!istype(depotarea))
+ return
+ if(target)
if(!seen_enemy)
seen_enemy = TRUE
if(!ranged)
@@ -148,11 +150,13 @@
/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/handle_automated_movement()
. = ..()
+ if(!istype(depotarea))
+ return
if(seen_enemy)
aggro_cycles++
if(alert_on_timeout && !raised_alert && aggro_cycles >= 60)
raise_alert("[name] has reported contact with hostile entity: [seen_enemy_name]")
- if(scan_cycles >= 15 && istype(depotarea))
+ if(scan_cycles >= 15)
scan_cycles = 0
if(!atoms_share_level(src, spawn_turf))
if(istype(loc, /obj/structure/closet))
@@ -187,6 +191,8 @@
depotarea.increase_alert(reason)
/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/death()
+ if(!istype(depotarea))
+ return ..()
if(alert_on_death)
if(seen_enemy_name)
raise_alert("[name] has died in combat with [seen_enemy_name].")
@@ -288,7 +294,7 @@
alert_on_spacing = FALSE
/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space/Process_Spacemove(var/movement_dir = 0)
- return
+ return TRUE
@@ -302,7 +308,7 @@
loot = list(/obj/effect/mob_spawn/human/corpse/syndicatecommando, /obj/item/melee/energy/sword/saber/red, /obj/item/shield/energy)
/mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(var/movement_dir = 0)
- return
+ return TRUE
/mob/living/simple_animal/hostile/syndicate/ranged
@@ -326,7 +332,7 @@
loot = list(/obj/effect/mob_spawn/human/corpse/syndicatecommando, /obj/item/gun/projectile/automatic/c20r)
/mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(var/movement_dir = 0)
- return
+ return TRUE
/mob/living/simple_animal/hostile/syndicate/ranged/space/autogib
loot = list()//gonna gibe, no loot.
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
index 23d7b30691b..d6d64096ff1 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
@@ -220,7 +220,7 @@ var/global/list/ts_spiderling_list = list()
// --------------------------------------------------------------------------------
/mob/living/simple_animal/hostile/poison/terror_spider/examine(mob/user)
- ..()
+ . = ..()
var/list/msgs = list()
if(stat == DEAD)
msgs += "It appears to be dead.\n"
@@ -241,7 +241,7 @@ var/global/list/ts_spiderling_list = list()
msgs += "It appears to be regenerating quickly."
if(killcount >= 1)
msgs += "It has blood dribbling from its mouth."
- to_chat(usr,msgs.Join("
"))
+ . += msgs.Join("
")
/mob/living/simple_animal/hostile/poison/terror_spider/New()
..()
diff --git a/code/modules/mob/living/simple_animal/posessed_object.dm b/code/modules/mob/living/simple_animal/posessed_object.dm
index f290dd7f2ef..acd71fdcaff 100644
--- a/code/modules/mob/living/simple_animal/posessed_object.dm
+++ b/code/modules/mob/living/simple_animal/posessed_object.dm
@@ -20,11 +20,11 @@
var/obj/item/possessed_item
/mob/living/simple_animal/possessed_object/examine(mob/user)
- possessed_item.examine(user)
+ . = possessed_item.examine(user)
if(health > (maxHealth / 30))
- to_chat(usr, "[src] appears to be floating without any support!")
+ . += "[src] appears to be floating without any support!"
else
- to_chat(usr, "[src] appears to be having trouble staying afloat!")
+ . += "[src] appears to be having trouble staying afloat!"
/mob/living/simple_animal/possessed_object/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y)
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index 47113341881..14714452850 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -46,3 +46,7 @@
/mob/living/simple_animal/shade/sword
universal_speak = 1
faction = list("neutral")
+
+/mob/living/simple_animal/shade/sword/Initialize(mapload)
+ .=..()
+ status_flags |= GODMODE
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 2e126412580..da08f257268 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -140,7 +140,7 @@
/mob/living/simple_animal/examine(mob/user)
. = ..()
if(stat == DEAD)
- to_chat(user, "Upon closer examination, [p_they()] appear[p_s()] to be dead.")
+ . += "Upon closer examination, [p_they()] appear[p_s()] to be dead."
/mob/living/simple_animal/updatehealth(reason = "none given")
..(reason)
@@ -605,7 +605,7 @@
real_name = P.tagname
/mob/living/simple_animal/regenerate_icons()
- cut_overlays()
if(pcollar && collar_type)
+ cut_overlays()
add_overlay("[collar_type]collar")
add_overlay("[collar_type]tag")
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/slime/death.dm b/code/modules/mob/living/simple_animal/slime/death.dm
new file mode 100644
index 00000000000..29a1adbd347
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/slime/death.dm
@@ -0,0 +1,32 @@
+/mob/living/simple_animal/slime/death(gibbed)
+ if(stat == DEAD)
+ return
+ if(!gibbed)
+ if(is_adult)
+ var/mob/living/simple_animal/slime/M = new(loc, colour)
+ M.rabid = TRUE
+ M.regenerate_icons()
+
+ is_adult = FALSE
+ maxHealth = 150
+ for(var/datum/action/innate/slime/reproduce/R in actions)
+ R.Remove(src)
+ var/datum/action/innate/slime/evolve/E = new
+ E.Grant(src)
+ revive()
+ regenerate_icons()
+ update_name()
+ return
+
+ if(buckled)
+ Feedstop(silent = TRUE) //releases ourselves from the mob we fed on.
+
+ stat = DEAD //Temporarily set to dead for icon updates
+ regenerate_icons()
+ stat = CONSCIOUS
+
+ return ..(gibbed)
+
+/mob/living/simple_animal/slime/gib()
+ death(TRUE)
+ qdel(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/slime/emote.dm b/code/modules/mob/living/simple_animal/slime/emote.dm
similarity index 95%
rename from code/modules/mob/living/carbon/slime/emote.dm
rename to code/modules/mob/living/simple_animal/slime/emote.dm
index c938ac17214..7fc7f4c5f87 100644
--- a/code/modules/mob/living/carbon/slime/emote.dm
+++ b/code/modules/mob/living/simple_animal/slime/emote.dm
@@ -1,4 +1,7 @@
-/mob/living/carbon/slime/emote(act, m_type = 1, message = null, force)
+/mob/living/simple_animal/slime/emote(act, m_type = 1, message = null, force)
+ if(stat)
+ return
+
if(findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
//param = copytext(act, t1 + 1, length(act) + 1)
@@ -99,6 +102,4 @@
loc.audible_message(message)
if(regenerate_icons)
- regenerate_icons()
-
- return
\ No newline at end of file
+ regenerate_icons()
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
new file mode 100644
index 00000000000..efd4c19d55c
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -0,0 +1,617 @@
+
+/mob/living/simple_animal/slime
+ var/AIproc = 0 // determines if the AI loop is activated
+ var/Atkcool = 0 // attack cooldown
+ var/Tempstun = 0 // temporary temperature stuns
+ var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while
+ var/SStun = 0 // stun variable
+
+
+/mob/living/simple_animal/slime/Life()
+ set invisibility = 0
+ if(notransform)
+ return
+ if(..())
+ if(buckled)
+ handle_feeding()
+ if(!stat) // Slimes in stasis don't lose nutrition, don't change mood and don't respond to speech
+ handle_nutrition()
+ if(QDELETED(src)) // Stop if the slime split during handle_nutrition()
+ return
+ reagents.remove_all(0.5 * REAGENTS_METABOLISM * reagents.reagent_list.len) //Slimes are such snowflakes
+ handle_targets()
+ if(!ckey)
+ handle_mood()
+ handle_speech()
+
+// Unlike most of the simple animals, slimes support UNCONSCIOUS
+/mob/living/simple_animal/slime/update_stat()
+ if(stat == UNCONSCIOUS && health > 0)
+ return
+ ..()
+
+/mob/living/simple_animal/slime/proc/AIprocess() // the master AI process
+
+ if(AIproc || stat || client)
+ return
+
+ var/hungry = 0
+ if (nutrition < get_starve_nutrition())
+ hungry = 2
+ else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition())
+ hungry = 1
+
+ AIproc = 1
+
+ while(AIproc && stat != DEAD && (attacked || hungry || rabid || buckled))
+ if(!canmove) //also covers buckling. Not sure why buckled is in the while condition if we're going to immediately break, honestly
+ break
+
+ if(!Target || client)
+ break
+
+ if(Target.health <= -70 || Target.stat == DEAD)
+ Target = null
+ AIproc = 0
+ break
+
+ if(Target)
+ if(locate(/mob/living/simple_animal/slime) in Target.buckled_mobs)
+ Target = null
+ AIproc = 0
+ break
+ if(!AIproc)
+ break
+
+ if(Target in view(1,src))
+ if(!CanFeedon(Target)) //If they're not able to be fed upon, ignore them.
+ if(!Atkcool)
+ Atkcool = TRUE
+ addtimer(VARSET_CALLBACK(src, Atkcool, FALSE), 4.5 SECONDS)
+
+ if(Target.Adjacent(src))
+ Target.attack_slime(src)
+ break
+ if(!Target.lying && prob(80))
+
+ if(Target.client && Target.health >= 20)
+ if(!Atkcool)
+ Atkcool = TRUE
+ addtimer(VARSET_CALLBACK(src, Atkcool, FALSE), 4.5 SECONDS)
+
+ if(Target.Adjacent(src))
+ Target.attack_slime(src)
+
+ else
+ if(!Atkcool && Target.Adjacent(src))
+ Feedon(Target)
+
+ else
+ if(!Atkcool && Target.Adjacent(src))
+ Feedon(Target)
+
+ else if(Target in view(7, src))
+ if(!Target.Adjacent(src))
+ // Bug of the month candidate: slimes were attempting to move to target only if it was directly next to them, which caused them to target things, but not approach them
+ step_to(src, Target)
+ else
+ Target = null
+ AIproc = 0
+ break
+
+ var/sleeptime = movement_delay()
+ if(sleeptime <= 0)
+ sleeptime = 1
+
+ sleep(sleeptime + 2) // this is about as fast as a player slime can go
+
+ AIproc = 0
+
+/mob/living/simple_animal/slime/handle_environment(datum/gas_mixture/environment)
+ if(!environment)
+ return
+
+ var/loc_temp = get_temperature(environment)
+
+ adjust_bodytemperature(adjust_body_temperature(bodytemperature, loc_temp, 1))
+
+ //Account for massive pressure differences
+
+ if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc
+ if(bodytemperature <= (T0C - 40)) // stun temperature
+ Tempstun = 1
+
+ if(bodytemperature <= (T0C - 50)) // hurt temperature
+ if(bodytemperature <= 50) // sqrting negative numbers is bad
+ adjustBruteLoss(200)
+ else
+ adjustBruteLoss(round(sqrt(bodytemperature)) * 2)
+
+ else
+ Tempstun = 0
+
+ updatehealth("handle environment")
+
+
+ return //TODO: DEFERRED
+
+/mob/living/simple_animal/slime/proc/adjust_body_temperature(current, loc_temp, boost)
+ var/temperature = current
+ var/difference = abs(current - loc_temp) //get difference
+ var/increments// = difference/10 //find how many increments apart they are
+ if(difference > 50)
+ increments = difference / 5
+ else
+ increments = difference / 10
+ var/change = increments * boost // Get the amount to change by (x per increment)
+ var/temp_change
+ if(current < loc_temp)
+ temperature = min(loc_temp, temperature+change)
+ else if(current > loc_temp)
+ temperature = max(loc_temp, temperature-change)
+ temp_change = (temperature - current)
+ return temp_change
+
+/mob/living/simple_animal/slime/handle_status_effects()
+ ..()
+ if(prob(30) && !stat)
+ adjustBruteLoss(-1)
+
+/mob/living/simple_animal/slime/proc/handle_feeding()
+ if(!ismob(buckled))
+ return
+ var/mob/M = buckled
+
+ if(stat)
+ Feedstop(silent = TRUE)
+
+ if(M.stat == DEAD) // our victim died
+ if(!client)
+ if(!rabid && !attacked)
+ if(M.LAssailant && M.LAssailant != M)
+ if(prob(50))
+ if(!(M.LAssailant in Friends))
+ Friends[M.LAssailant] = 1
+ else
+ ++Friends[M.LAssailant]
+ else
+ to_chat(src, "This subject does not have a strong enough life energy anymore...")
+
+ if(M.client && ishuman(M))
+ if(prob(85))
+ rabid = 1 //we go rabid after finishing to feed on a human with a client.
+
+ Feedstop()
+ return
+
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.adjustCloneLoss(rand(2, 4))
+ C.adjustToxLoss(rand(1, 2))
+
+ if(prob(10) && C.client)
+ to_chat(C, "[pick("You can feel your body becoming weak!", \
+ "You feel like you're about to die!", \
+ "You feel every part of your body screaming in agony!", \
+ "A low, rolling pain passes through your body!", \
+ "Your body feels as if it's falling apart!", \
+ "You feel extremely weak!", \
+ "A sharp, deep pain bathes every inch of your body!")]")
+
+ else if(isanimal(M))
+ var/mob/living/simple_animal/SA = M
+
+ var/totaldamage = 0 //total damage done to this unfortunate animal
+ totaldamage += SA.adjustCloneLoss(rand(2, 4))
+ totaldamage += SA.adjustToxLoss(rand(1, 2))
+
+ if(totaldamage <= 0) //if we did no(or negative!) damage to it, stop
+ Feedstop(0, 0)
+ return
+
+ else
+ Feedstop(0, 0)
+ return
+
+ add_nutrition(rand(7, 15))
+
+ //Heal yourself.
+ adjustBruteLoss(-3)
+
+/mob/living/simple_animal/slime/proc/handle_nutrition()
+
+ if(docile) //God as my witness, I will never go hungry again
+ set_nutrition(700) //fuck you for using the base nutrition var
+ return
+
+ if(prob(15))
+ adjust_nutrition(-(1 + is_adult))
+
+ if(nutrition <= 0)
+ set_nutrition(0)
+ if(prob(75))
+ adjustBruteLoss(rand(0, 5))
+
+ else if(nutrition >= get_grow_nutrition() && amount_grown < SLIME_EVOLUTION_THRESHOLD)
+ adjust_nutrition(-20)
+ amount_grown++
+ update_action_buttons_icon()
+
+ if(amount_grown >= SLIME_EVOLUTION_THRESHOLD && !buckled && !Target && !ckey)
+ if(is_adult)
+ Reproduce()
+ else
+ Evolve()
+
+/mob/living/simple_animal/slime/proc/add_nutrition(nutrition_to_add = 0)
+ set_nutrition(min((nutrition + nutrition_to_add), get_max_nutrition()))
+ if(nutrition >= get_grow_nutrition())
+ if(powerlevel<10)
+ if(prob(30-powerlevel*2))
+ powerlevel++
+ else if(nutrition >= get_hunger_nutrition() + 100) //can't get power levels unless you're a bit above hunger level.
+ if(powerlevel<5)
+ if(prob(25-powerlevel*5))
+ powerlevel++
+
+
+
+
+/mob/living/simple_animal/slime/proc/handle_targets()
+ update_canmove()
+ if(Tempstun)
+ if(!buckled) // not while they're eating!
+ canmove = 0
+ else
+ canmove = 1
+
+ if(attacked > 50)
+ attacked = 50
+
+ if(attacked > 0)
+ attacked--
+
+ if(Discipline > 0)
+
+ if(Discipline >= 5 && rabid)
+ if(prob(60))
+ rabid = 0
+
+ if(prob(10))
+ Discipline--
+
+ if(!client)
+ if(!canmove)
+ return
+
+ if(buckled)
+ return // if it's eating someone already, continue eating!
+
+ if(Target)
+ --target_patience
+ if (target_patience <= 0 || SStun > world.time || Discipline || attacked || docile) // Tired of chasing or something draws out attention
+ target_patience = 0
+ Target = null
+
+ if(AIproc && SStun > world.time)
+ return
+
+ var/hungry = 0 // determines if the slime is hungry
+
+ if (nutrition < get_starve_nutrition())
+ hungry = 2
+ else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition())
+ hungry = 1
+
+ if(hungry == 2 && !client) // if a slime is starving, it starts losing its friends
+ if(Friends.len > 0 && prob(1))
+ var/mob/nofriend = pick(Friends)
+ --Friends[nofriend]
+
+ if(!Target)
+ if(will_hunt() && hungry || attacked || rabid) // Only add to the list if we need to
+ var/list/targets = list()
+
+ for(var/mob/living/L in view(7,src))
+
+ if(isslime(L) || L.stat == DEAD) // Ignore other slimes and dead mobs
+ continue
+
+ if(L in Friends) // No eating friends!
+ continue
+
+ var/ally = FALSE
+ for(var/F in faction)
+ if(F == "neutral") //slimes are neutral so other mobs not target them, but they can target neutral mobs
+ continue
+ if(F in L.faction)
+ ally = TRUE
+ break
+ if(ally)
+ continue
+
+ if(issilicon(L) && (rabid || attacked)) // They can't eat silicons, but they can glomp them in defence
+ targets += L // Possible target found!
+
+ if(locate(/mob/living/simple_animal/slime) in L.buckled_mobs) // Only one slime can latch on at a time.
+ continue
+
+ targets += L // Possible target found!
+
+ if(targets.len > 0)
+ if(attacked || rabid || hungry == 2)
+ Target = targets[1] // I am attacked and am fighting back or so hungry I don't even care
+ else
+ for(var/mob/living/carbon/C in targets)
+ if(!Discipline && prob(5))
+ if(ishuman(C) || isalienadult(C))
+ Target = C
+ break
+
+ if(islarva(C) || issmall(C))
+ Target = C
+ break
+
+ if (Target)
+ target_patience = rand(5, 7)
+ if(is_adult)
+ target_patience += 3
+
+ if(!Target) // If we have no target, we are wandering or following orders
+ if (Leader)
+ if(holding_still)
+ holding_still = max(holding_still - 1, 0)
+ else if(canmove && isturf(loc))
+ step_to(src, Leader)
+
+ else if(hungry)
+ if (holding_still)
+ holding_still = max(holding_still - hungry, 0)
+ else if(canmove && isturf(loc) && prob(50))
+ step(src, pick(cardinal))
+
+ else
+ if(holding_still)
+ holding_still = max(holding_still - 1, 0)
+ else if (docile && pulledby)
+ holding_still = 10
+ else if(canmove && isturf(loc) && prob(33))
+ step(src, pick(cardinal))
+ else if(!AIproc)
+ INVOKE_ASYNC(src, .proc/AIprocess)
+
+/mob/living/simple_animal/slime/handle_automated_movement()
+ return //slime random movement is currently handled in handle_targets()
+
+/mob/living/simple_animal/slime/handle_automated_speech()
+ return //slime random speech is currently handled in handle_speech()
+
+/mob/living/simple_animal/slime/proc/handle_mood()
+ var/newmood = ""
+ if (rabid || attacked)
+ newmood = "angry"
+ else if (docile)
+ newmood = ":3"
+ else if (Target)
+ newmood = "mischievous"
+
+ if (!newmood)
+ if (Discipline && prob(25))
+ newmood = "pout"
+ else if (prob(1))
+ newmood = pick("sad", ":3", "pout")
+
+ if ((mood == "sad" || mood == ":3" || mood == "pout") && !newmood)
+ if(prob(75))
+ newmood = mood
+
+ if(newmood != mood) // This is so we don't redraw them every time
+ mood = newmood
+ regenerate_icons()
+
+/mob/living/simple_animal/slime/proc/handle_speech()
+ //Speech understanding starts here
+ var/to_say
+ if(speech_buffer.len > 0)
+ var/who = speech_buffer[1] // Who said it?
+ var/phrase = speech_buffer[2] // What did they say?
+ if((findtext(phrase, num2text(number)) || findtext(phrase, "slimes"))) // Talking to us
+ if(findtext(phrase, "hello") || findtext(phrase, "hi"))
+ to_say = pick("Hello...", "Hi...")
+ else if(findtext(phrase, "follow"))
+ if(Leader)
+ if(Leader == who) // Already following him
+ to_say = pick("Yes...", "Lead...", "Follow...")
+ else if(Friends[who] > Friends[Leader]) // VIVA
+ Leader = who
+ to_say = "Yes... I follow [who]..."
+ else
+ to_say = "No... I follow [Leader]..."
+ else
+ if(Friends[who] >= SLIME_FRIENDSHIP_FOLLOW)
+ Leader = who
+ to_say = "I follow..."
+ else // Not friendly enough
+ to_say = pick("No...", "I no follow...")
+ else if(findtext(phrase, "stop"))
+ if(buckled) // We are asked to stop feeding
+ if (Friends[who] >= SLIME_FRIENDSHIP_STOPEAT)
+ Feedstop()
+ Target = null
+ if (Friends[who] < SLIME_FRIENDSHIP_STOPEAT_NOANGRY)
+ --Friends[who]
+ to_say = "Grrr..." // I'm angry but I do it
+ else
+ to_say = "Fine..."
+ else if(Target) // We are asked to stop chasing
+ if(Friends[who] >= SLIME_FRIENDSHIP_STOPCHASE)
+ Target = null
+ if(Friends[who] < SLIME_FRIENDSHIP_STOPCHASE_NOANGRY)
+ --Friends[who]
+ to_say = "Grrr..." // I'm angry but I do it
+ else
+ to_say = "Fine..."
+ else if(Leader) // We are asked to stop following
+ if(Leader == who)
+ to_say = "Yes... I stay..."
+ Leader = null
+ else
+ if(Friends[who] > Friends[Leader])
+ Leader = null
+ to_say = "Yes... I stop..."
+ else
+ to_say = "No... keep follow..."
+ else if(findtext(phrase, "stay"))
+ if(Leader)
+ if (Leader == who)
+ holding_still = Friends[who] * 10
+ to_say = "Yes... stay..."
+ else if(Friends[who] > Friends[Leader])
+ holding_still = (Friends[who] - Friends[Leader]) * 10
+ to_say = "Yes... stay..."
+ else
+ to_say = "No... keep follow..."
+ else
+ if(Friends[who] >= SLIME_FRIENDSHIP_STAY)
+ holding_still = Friends[who] * 10
+ to_say = "Yes... stay..."
+ else
+ to_say = "No... won't stay..."
+ else if(findtext(phrase, "attack"))
+ if(rabid && prob(20))
+ Target = who
+ AIprocess() //Wake up the slime's Target AI, needed otherwise this doesn't work
+ to_say = "ATTACK!?!?"
+ else if(Friends[who] >= SLIME_FRIENDSHIP_ATTACK)
+ for(var/mob/living/L in view(7,src)-list(src,who))
+ if(findtext(phrase, lowertext(L.name)))
+ if(isslime(L))
+ to_say = "NO... [L] slime friend"
+ --Friends[who] //Don't ask a slime to attack its friend
+ else if(!Friends[L] || Friends[L] < 1)
+ Target = L
+ AIprocess()//Wake up the slime's Target AI, needed otherwise this doesn't work
+ to_say = "Ok... I attack [Target]"
+ else
+ to_say = "No... like [L] ..."
+ --Friends[who] //Don't ask a slime to attack its friend
+ break
+ else
+ to_say = "No... no listen"
+
+ speech_buffer = list()
+
+ //Speech starts here
+ if(to_say)
+ say (to_say)
+ else if(prob(1))
+ emote(pick("bounce", "sway", "light", "vibrate", "jiggle"))
+ else
+ var/t = 10
+ var/slimes_near = 0
+ var/dead_slimes = 0
+ var/friends_near = list()
+ for(var/mob/living/L in view(7,src))
+ if(isslime(L) && L != src)
+ ++slimes_near
+ if (L.stat == DEAD)
+ ++dead_slimes
+ if(L in Friends)
+ t += 20
+ friends_near += L
+ if(nutrition < get_hunger_nutrition())
+ t += 10
+ if(nutrition < get_starve_nutrition())
+ t += 10
+ if(prob(2) && prob(t))
+ var/phrases = list()
+ if(Target)
+ phrases += "[Target]... look yummy..."
+ if(nutrition < get_starve_nutrition())
+ phrases += "So... hungry..."
+ phrases += "Very... hungry..."
+ phrases += "Need... food..."
+ phrases += "Must... eat..."
+ else if(nutrition < get_hunger_nutrition())
+ phrases += "Hungry..."
+ phrases += "Where food?"
+ phrases += "I want to eat..."
+ phrases += "Rawr..."
+ phrases += "Blop..."
+ phrases += "Blorble..."
+ if(rabid || attacked)
+ phrases += "Hrr..."
+ phrases += "Nhuu..."
+ phrases += "Unn..."
+ if(mood == ":3")
+ phrases += "Purr..."
+ if(attacked)
+ phrases += "Grrr..."
+ if(bodytemperature < T0C)
+ phrases += "Cold..."
+ if(bodytemperature < T0C - 30)
+ phrases += "So... cold..."
+ phrases += "Very... cold..."
+ if(bodytemperature < T0C - 50)
+ phrases += "..."
+ phrases += "C... c..."
+ if(buckled)
+ phrases += "Nom..."
+ phrases += "Yummy..."
+ if(powerlevel > 3)
+ phrases += "Bzzz..."
+ if(powerlevel > 5)
+ phrases += "Zap..."
+ if(powerlevel > 8)
+ phrases += "Zap... Bzz..."
+ if(mood == "sad")
+ phrases += "Bored..."
+ if(slimes_near)
+ phrases += "Slime friend..."
+ if(slimes_near > 1)
+ phrases += "Slime friends..."
+ if(dead_slimes)
+ phrases += "What happened?"
+ if(!slimes_near)
+ phrases += "Lonely..."
+ for(var/M in friends_near)
+ phrases += "[M]... friend..."
+ if(nutrition < get_hunger_nutrition())
+ phrases += "[M]... feed me..."
+ if(!stat)
+ say (pick(phrases))
+
+/mob/living/simple_animal/slime/proc/get_max_nutrition() // Can't go above it
+ if(is_adult)
+ return 1200
+ else
+ return 1000
+
+/mob/living/simple_animal/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat
+ if(is_adult)
+ return 1000
+ else
+ return 800
+
+/mob/living/simple_animal/slime/proc/get_hunger_nutrition() // Below it we will always eat
+ if(is_adult)
+ return 600
+ else
+ return 500
+
+/mob/living/simple_animal/slime/proc/get_starve_nutrition() // Below it we will eat before everything else
+ if(is_adult)
+ return 300
+ else
+ return 200
+
+/mob/living/simple_animal/slime/proc/will_hunt(hunger = -1) // Check for being stopped from feeding and chasing
+ if(docile)
+ return 0
+ if(hunger == 2 || rabid || attacked)
+ return 1
+ if(Leader)
+ return 0
+ if(holding_still)
+ return 0
+ return 1
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm
new file mode 100644
index 00000000000..bd9d001f12f
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/slime/powers.dm
@@ -0,0 +1,215 @@
+#define SIZE_DOESNT_MATTER -1
+#define BABIES_ONLY 0
+#define ADULTS_ONLY 1
+
+#define NO_GROWTH_NEEDED 0
+#define GROWTH_NEEDED 1
+
+/datum/action/innate/slime
+ check_flags = AB_CHECK_CONSCIOUS
+ icon_icon = 'icons/mob/actions/actions_slime.dmi'
+ background_icon_state = "bg_alien"
+ var/needs_growth = NO_GROWTH_NEEDED
+
+/datum/action/innate/slime/IsAvailable()
+ if(..())
+ var/mob/living/simple_animal/slime/S = owner
+ if(needs_growth == GROWTH_NEEDED)
+ if(S.amount_grown >= SLIME_EVOLUTION_THRESHOLD)
+ return 1
+ return 0
+ return 1
+
+/mob/living/simple_animal/slime/verb/Feed()
+ set category = "Slime"
+ set desc = "This will let you feed on any valid creature in the surrounding area. This should also be used to halt the feeding process."
+
+ if(stat)
+ return 0
+
+ var/list/choices = list()
+ for(var/mob/living/C in view(1,src))
+ if(C!=src && Adjacent(C))
+ choices += C
+
+ var/mob/living/M = input(src,"Who do you wish to feed on?") in null|choices
+ if(!M)
+ return 0
+ if(CanFeedon(M))
+ Feedon(M)
+ return 1
+
+/datum/action/innate/slime/feed
+ name = "Feed"
+ button_icon_state = "slimeeat"
+
+
+/datum/action/innate/slime/feed/Activate()
+ var/mob/living/simple_animal/slime/S = owner
+ S.Feed()
+
+/mob/living/simple_animal/slime/proc/CanFeedon(mob/living/M, silent = FALSE)
+ if(!Adjacent(M))
+ return FALSE
+
+ if(buckled)
+ Feedstop()
+ return FALSE
+
+ if(issilicon(M))
+ return FALSE
+
+ if(isanimal(M))
+ var/mob/living/simple_animal/S = M
+ if(S.damage_coeff[TOX] <= 0 && S.damage_coeff[CLONE] <= 0) //The creature wouldn't take any damage, it must be too weird even for us.
+ if(silent)
+ return FALSE
+ to_chat(src, "[pick("This subject is incompatible", \
+ "This subject does not have life energy", "This subject is empty", \
+ "I am not satisified", "I can not feed from this subject", \
+ "I do not feel nourished", "This subject is not food")]!")
+ return FALSE
+
+ if(isslime(M))
+ if(silent)
+ return FALSE
+ to_chat(src, "I can't latch onto another slime...")
+ return FALSE
+
+ if(docile)
+ if(silent)
+ return FALSE
+ to_chat(src, "I'm not hungry anymore...")
+ return FALSE
+
+ if(stat)
+ if(silent)
+ return FALSE
+ to_chat(src, "I must be conscious to do this...")
+ return FALSE
+
+ if(M.stat == DEAD)
+ if(silent)
+ return FALSE
+ to_chat(src, "This subject does not have a strong enough life energy...")
+ return FALSE
+
+ if(locate(/mob/living/simple_animal/slime) in M.buckled_mobs)
+ if(silent)
+ return FALSE
+ to_chat(src, "Another slime is already feeding on this subject...")
+ return FALSE
+ return TRUE
+
+/mob/living/simple_animal/slime/proc/Feedon(mob/living/M)
+ M.unbuckle_all_mobs(force = TRUE) //Slimes rip other mobs (eg: shoulder parrots) off (Slimes Vs Slimes is already handled in CanFeedon())
+ if(M.buckle_mob(src, force = TRUE))
+ layer = M.layer + 0.01 //appear above the target mob
+ M.visible_message("[name] has latched onto [M]!", \
+ "[name] has latched onto [M]!")
+ else
+ to_chat(src, "I have failed to latch onto the subject!")
+
+/mob/living/simple_animal/slime/proc/Feedstop(silent = FALSE, living = 1)
+ if(buckled)
+ if(!living)
+ to_chat(src, "[pick("This subject is incompatible", \
+ "This subject does not have life energy", "This subject is empty", \
+ "I am not satisified", "I can not feed from this subject", \
+ "I do not feel nourished", "This subject is not food")]!")
+ if(!silent)
+ visible_message("[src] has let go of [buckled]!", \
+ "I stopped feeding.")
+ layer = initial(layer)
+ buckled.unbuckle_mob(src,force=TRUE)
+
+/mob/living/simple_animal/slime/verb/Evolve()
+ set category = "Slime"
+ set desc = "This will let you evolve from baby to adult slime."
+
+ if(stat)
+ to_chat(src, "I must be conscious to do this...")
+ return
+ if(!is_adult)
+ if(amount_grown >= SLIME_EVOLUTION_THRESHOLD)
+ is_adult = 1
+ maxHealth = 200
+ amount_grown = 0
+ for(var/datum/action/innate/slime/evolve/E in actions)
+ E.Remove(src)
+ regenerate_icons()
+ update_name()
+ else
+ to_chat(src, "I am not ready to evolve yet...")
+ else
+ to_chat(src, "I have already evolved...")
+
+/datum/action/innate/slime/evolve
+ name = "Evolve"
+ button_icon_state = "slimegrow"
+ needs_growth = GROWTH_NEEDED
+
+/datum/action/innate/slime/evolve/Activate()
+ var/mob/living/simple_animal/slime/S = owner
+ S.Evolve()
+ if(S.is_adult)
+ var/datum/action/innate/slime/reproduce/A = new
+ A.Grant(S)
+
+/mob/living/simple_animal/slime/verb/Reproduce()
+ set category = "Slime"
+ set desc = "This will make you split into four Slimes."
+
+ if(stat)
+ to_chat(src, "I must be conscious to do this...")
+ return
+
+ if(is_adult)
+ if(amount_grown >= SLIME_EVOLUTION_THRESHOLD)
+ if(stat)
+ to_chat(src, "I must be conscious to do this...")
+ return
+
+ var/list/babies = list()
+ var/new_nutrition = round(nutrition * 0.9)
+ var/new_powerlevel = round(powerlevel / 4)
+ for(var/i=1,i<=4,i++)
+ var/child_colour
+ if(mutation_chance >= 100)
+ child_colour = "rainbow"
+ else if(prob(mutation_chance))
+ child_colour = slime_mutation[rand(1,4)]
+ else
+ child_colour = colour
+ var/mob/living/simple_animal/slime/M
+ M = new(loc, child_colour)
+ if(ckey)
+ M.set_nutrition(new_nutrition) //Player slimes are more robust at spliting. Once an oversight of poor copypasta, now a feature!
+ M.powerlevel = new_powerlevel
+ if(i != 1)
+ step_away(M,src)
+ M.Friends = Friends.Copy()
+ babies += M
+ M.mutation_chance = Clamp(mutation_chance+(rand(5,-5)),0,100)
+ feedback_add_details("slime_babies_born", "slimebirth_[replacetext(M.colour," ","_")]")
+
+ var/mob/living/simple_animal/slime/new_slime = pick(babies)
+ new_slime.a_intent = INTENT_HARM
+ if(src.mind)
+ src.mind.transfer_to(new_slime)
+ else
+ new_slime.key = src.key
+ qdel(src)
+ else
+ to_chat(src, "I am not ready to reproduce yet...")
+ else
+ to_chat(src, "I am not old enough to reproduce yet...")
+
+/datum/action/innate/slime/reproduce
+ name = "Reproduce"
+ button_icon_state = "slimesplit"
+ needs_growth = GROWTH_NEEDED
+
+/datum/action/innate/slime/reproduce/Activate()
+ var/mob/living/simple_animal/slime/S = owner
+ S.Reproduce()
diff --git a/code/modules/mob/living/simple_animal/slime/say.dm b/code/modules/mob/living/simple_animal/slime/say.dm
new file mode 100644
index 00000000000..01269aab8aa
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/slime/say.dm
@@ -0,0 +1,18 @@
+/mob/living/simple_animal/slime/say_quote(text, datum/language/speaking)
+ var/verb = "blorbles"
+ var/ending = copytext(text, length(text))
+
+ if(ending == "?")
+ verb = "inquisitively blorbles"
+ else if(ending == "!")
+ verb = "loudly blorbles"
+
+ return verb
+
+/mob/living/simple_animal/slime/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol)
+ if(speaker != src && !stat)
+ if(speaker in Friends)
+ speech_buffer = list()
+ speech_buffer.Add(speaker)
+ speech_buffer.Add(lowertext(html_decode(multilingual_to_message(message_pieces))))
+ ..()
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
new file mode 100644
index 00000000000..d9326b78ab3
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -0,0 +1,506 @@
+/mob/living/simple_animal/slime
+ name = "grey baby slime (123)"
+ icon = 'icons/mob/slimes.dmi'
+ icon_state = "grey baby slime"
+ pass_flags = PASSTABLE | PASSGRILLE
+ ventcrawler = VENTCRAWLER_ALWAYS
+ gender = NEUTER
+ var/is_adult = 0
+ var/docile = 0
+ faction = list("slime", "neutral")
+
+ harm_intent_damage = 5
+ icon_living = "grey baby slime"
+ icon_dead = "grey baby slime dead"
+ response_help = "pets"
+ response_disarm = "shoos"
+ response_harm = "stomps on"
+ emote_see = list("jiggles", "bounces in place")
+ speak_emote = list("blorbles")
+
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+
+ maxHealth = 150
+ health = 150
+ healable = 0
+ gender = NEUTER
+
+ see_in_dark = 8
+
+ // canstun and canknockdown don't affect slimes because they ignore stun and knockdown variables
+ // for the sake of cleanliness, though, here they are.
+ status_flags = CANPARALYSE | CANPUSH
+
+ var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside
+ var/mutation_chance = 30 // Chance of mutating, should be between 25 and 35
+
+ var/powerlevel = 0 // 1-10 controls how much electricity they are generating
+ var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces
+
+ var/number = 0 // Used to understand when someone is talking to it
+
+ var/mob/living/Target = null // AI variable - tells the slime to hunt this down
+ var/mob/living/Leader = null // AI variable - tells the slime to follow this person
+
+ var/attacked = 0 // Determines if it's been attacked recently. Can be any number, is a cooloff-ish variable
+ var/rabid = 0 // If set to 1, the slime will attack and eat anything it comes in contact with
+ var/holding_still = 0 // AI variable, cooloff-ish for how long it's going to stay in one place
+ var/target_patience = 0 // AI variable, cooloff-ish for how long it's going to follow its target
+
+ var/list/Friends = list() // A list of friends; they are not considered targets for feeding; passed down after splitting
+
+ var/list/speech_buffer = list() // Last phrase said near it and person who said it
+
+ var/mood = "" // To show its face
+ var/mutator_used = FALSE //So you can't shove a dozen mutators into a single slime
+ var/force_stasis = FALSE
+
+ var/static/regex/slime_name_regex = new("\\w+ (baby|adult) slime \\(\\d+\\)")
+ ///////////TIME FOR SUBSPECIES
+
+ var/colour = "grey"
+ var/coretype = /obj/item/slime_extract/grey
+ var/list/slime_mutation[4]
+
+ var/static/list/slime_colours = list("rainbow", "grey", "purple", "metal", "orange",
+ "blue", "dark blue", "dark purple", "yellow", "silver", "pink", "red",
+ "gold", "green", "adamantine", "oil", "light pink", "bluespace",
+ "cerulean", "sepia", "black", "pyrite")
+
+ ///////////CORE-CROSSING CODE
+
+ var/effectmod //What core modification is being used.
+ var/applied = 0 //How many extracts of the modtype have been applied.
+
+
+/mob/living/simple_animal/slime/Initialize(mapload, new_colour = "grey", new_is_adult = FALSE)
+ var/datum/action/innate/slime/feed/F = new
+ F.Grant(src)
+
+ is_adult = new_is_adult
+
+ if(is_adult)
+ var/datum/action/innate/slime/reproduce/R = new
+ R.Grant(src)
+ health = 200
+ maxHealth = 200
+ else
+ var/datum/action/innate/slime/evolve/E = new
+ E.Grant(src)
+ create_reagents(100)
+ set_colour(new_colour)
+ . = ..()
+ set_nutrition(700)
+ add_language("Bubblish")
+
+/mob/living/simple_animal/slime/Destroy()
+ for(var/A in actions)
+ var/datum/action/AC = A
+ AC.Remove(src)
+ for(var/obj/machinery/computer/camera_advanced/xenobio/X in GLOB.machines)
+ if(src in X.stored_slimes)
+ X.stored_slimes -= src
+ return ..()
+
+/mob/living/simple_animal/slime/proc/set_colour(new_colour)
+ colour = new_colour
+ update_name()
+ slime_mutation = mutation_table(colour)
+ var/sanitizedcolour = replacetext(colour, " ", "")
+ coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]")
+ regenerate_icons()
+
+/mob/living/simple_animal/slime/proc/update_name()
+ if(slime_name_regex.Find(name))
+ number = rand(1, 1000)
+ name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
+ real_name = name
+
+/mob/living/simple_animal/slime/proc/random_colour()
+ set_colour(pick(slime_colours))
+
+/mob/living/simple_animal/slime/regenerate_icons()
+ cut_overlays()
+ var/icon_text = "[colour] [is_adult ? "adult" : "baby"] slime"
+ icon_dead = "[icon_text] dead"
+ if(stat != DEAD)
+ icon_state = icon_text
+ if(mood && !stat)
+ add_overlay("aslime-[mood]")
+ else
+ icon_state = icon_dead
+ ..()
+
+/mob/living/simple_animal/slime/movement_delay()
+ if(bodytemperature >= 330.23) // 135 F or 57.08 C
+ return -1 // slimes become supercharged at high temperatures
+
+ . = ..()
+
+ var/health_deficiency = (maxHealth - health)
+ if(health_deficiency >= 45)
+ . += (health_deficiency / 25)
+
+ if(bodytemperature < 183.222)
+ . += (283.222 - bodytemperature) / 10 * 1.75
+
+ if(reagents)
+ if(reagents.has_reagent("morphine")) // morphine slows slimes down
+ . *= 2
+
+ if(reagents.has_reagent("frostoil")) // Frostoil also makes them move VEEERRYYYYY slow
+ . *= 5
+
+ if(health <= 0) // if damaged, the slime moves twice as slow
+ . *= 2
+
+ . += config.slime_delay
+
+/mob/living/simple_animal/slime/handle_hud_icons_health()
+ if(hud_used)
+ if(!client)
+ return
+
+ if(healths)
+ var/severity = 0
+ var/healthpercent = (health / maxHealth) * 100
+ switch(healthpercent)
+ if(100 to INFINITY)
+ healths.icon_state = "slime_health0"
+ if(80 to 100)
+ healths.icon_state = "slime_health1"
+ severity = 1
+ if(60 to 80)
+ healths.icon_state = "slime_health2"
+ severity = 2
+ if(40 to 60)
+ healths.icon_state = "slime_health3"
+ severity = 3
+ if(20 to 40)
+ healths.icon_state = "slime_health4"
+ severity = 4
+ if(1 to 20)
+ healths.icon_state = "slime_health5"
+ severity = 5
+ else
+ healths.icon_state = "slime_health7"
+ severity = 6
+ if(severity > 0)
+ overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
+ else
+ clear_fullscreen("brute")
+
+/mob/living/simple_animal/slime/ObjBump(obj/O)
+ if(!client && powerlevel > 0)
+ var/probab = 10
+ switch(powerlevel)
+ if(1 to 2)
+ probab = 20
+ if(3 to 4)
+ probab = 30
+ if(5 to 6)
+ probab = 40
+ if(7 to 8)
+ probab = 60
+ if(9)
+ probab = 70
+ if(10)
+ probab = 95
+ if(prob(probab))
+ if(istype(O, /obj/structure/window) || istype(O, /obj/structure/grille))
+ if(nutrition <= get_hunger_nutrition() && !Atkcool)
+ if (is_adult || prob(5))
+ O.attack_slime(src)
+ Atkcool = TRUE
+ addtimer(VARSET_CALLBACK(src, Atkcool, FALSE), 4.5 SECONDS)
+
+/mob/living/simple_animal/slime/Process_Spacemove(movement_dir = 0)
+ return 2
+
+/mob/living/simple_animal/slime/Stat()
+ if(..())
+
+ if(!docile)
+ stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]")
+ if(amount_grown >= SLIME_EVOLUTION_THRESHOLD)
+ if(is_adult)
+ stat(null, "You can reproduce!")
+ else
+ stat(null, "You can evolve!")
+
+ if(stat == UNCONSCIOUS)
+ stat(null,"You are knocked out by high levels of BZ!")
+ else
+ stat(null,"Power Level: [powerlevel]")
+
+
+/mob/living/simple_animal/slime/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
+ if(!forced)
+ amount = -abs(amount)
+ return ..() //Heals them
+
+/mob/living/simple_animal/slime/bullet_act(obj/item/projectile/Proj)
+ if(!Proj)
+ return
+ attacked += 10
+ if((Proj.damage_type == BURN))
+ adjustBruteLoss(-abs(Proj.damage)) //fire projectiles heals slimes.
+ Proj.on_hit(src)
+ else
+ ..(Proj)
+ return FALSE
+
+/mob/living/simple_animal/slime/emp_act(severity)
+ ..()
+ powerlevel = 0 // oh no, the power!
+
+/mob/living/simple_animal/slime/MouseDrop(atom/movable/A)
+ if(isliving(A) && A != src && usr == src)
+ var/mob/living/Food = A
+ if(CanFeedon(Food))
+ Feedon(Food)
+ return ..()
+
+/mob/living/simple_animal/slime/unEquip(obj/item/I)
+ return
+
+/mob/living/simple_animal/slime/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
+ return
+
+/mob/living/simple_animal/slime/attack_ui(slot)
+ return
+
+/mob/living/simple_animal/slime/attack_slime(mob/living/simple_animal/slime/M)
+ if(..()) //successful slime attack
+ if(M == src)
+ return
+ if(buckled)
+ Feedstop(silent = TRUE)
+ visible_message("[M] pulls [src] off!", \
+ "You pull [src] off!")
+ return
+ attacked += 5
+ if(nutrition >= 100) //steal some nutrition. negval handled in life()
+ adjust_nutrition(-(50 + (40 * M.is_adult)))
+ M.add_nutrition(50 + (40 * M.is_adult))
+ if(health > 0)
+ M.adjustBruteLoss(-10 + (-10 * M.is_adult))
+ M.updatehealth()
+
+/mob/living/simple_animal/slime/attack_animal(mob/living/simple_animal/M)
+ . = ..()
+ if(.)
+ attacked += 10
+
+/mob/living/simple_animal/slime/attack_larva(mob/living/carbon/alien/larva/L)
+ if(..()) //successful larva bite.
+ attacked += 10
+
+/mob/living/simple_animal/slime/attack_hulk(mob/living/carbon/human/user)
+ if(user.a_intent == INTENT_HARM)
+ discipline_slime(user)
+ return ..()
+
+/mob/living/simple_animal/slime/attack_hand(mob/living/carbon/human/M)
+ if(buckled)
+ M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
+ if(buckled == M)
+ if(prob(60))
+ M.visible_message("[M] attempts to wrestle \the [name] off!", \
+ "You attempt to wrestle \the [name] off!")
+ playsound(loc, 'sound/weapons/punchmiss.ogg', 25, TRUE, -1)
+
+ else
+ M.visible_message("[M] manages to wrestle \the [name] off!", \
+ "You manage to wrestle \the [name] off!")
+ playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
+
+ discipline_slime(M)
+
+ else
+ if(prob(30))
+ buckled.visible_message("[M] attempts to wrestle \the [name] off of [buckled]!", \
+ "[M] attempts to wrestle \the [name] off of you!")
+ playsound(loc, 'sound/weapons/punchmiss.ogg', 25, TRUE, -1)
+
+ else
+ buckled.visible_message("[M] manages to wrestle \the [name] off of [buckled]!", \
+ "[M] manage to wrestle \the [name] off of you!")
+ playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
+
+ discipline_slime(M)
+ else
+ if(stat == DEAD && surgeries.len)
+ if(M.a_intent == INTENT_HELP || M.a_intent == INTENT_DISARM)
+ for(var/datum/surgery/S in surgeries)
+ if(S.next_step(M, src))
+ return 1
+ if(..()) //successful attack
+ attacked += 10
+
+/mob/living/simple_animal/slime/attack_alien(mob/living/carbon/alien/humanoid/M)
+ if(..()) //if harm or disarm intent.
+ attacked += 10
+ discipline_slime(M)
+
+
+/mob/living/simple_animal/slime/attackby(obj/item/I, mob/living/user, params)
+ if(stat == DEAD && surgeries.len)
+ if(user.a_intent == INTENT_HELP || user.a_intent == INTENT_DISARM)
+ for(var/datum/surgery/S in surgeries)
+ if(S.next_step(user, src))
+ return 1
+ if(istype(I, /obj/item/stack/sheet/mineral/plasma) && !stat) //Let's you feed slimes plasma.
+ if(user in Friends)
+ ++Friends[user]
+ else
+ Friends[user] = 1
+ to_chat(user, "You feed the slime the plasma. It chirps happily.")
+ var/obj/item/stack/sheet/mineral/plasma/S = I
+ S.use(1)
+ return
+ if(I.force > 0)
+ attacked += 10
+ if(prob(25))
+ user.do_attack_animation(src)
+ user.changeNext_move(CLICK_CD_MELEE)
+ to_chat(user, "[I] passes right through [src]!")
+ return
+ if(Discipline && prob(50)) // wow, buddy, why am I getting attacked??
+ Discipline = 0
+ if(I.force >= 3)
+ var/force_effect = 2 * I.force
+ if(is_adult)
+ force_effect = round(I.force / 2)
+ if(prob(10 + force_effect))
+ discipline_slime(user)
+/* if(istype(I, /obj/item/storage/bag/bio))
+ var/obj/item/storage/P = I
+ if(!effectmod)
+ to_chat(user, "The slime is not currently being mutated.")
+ return
+ var/hasOutput = FALSE //Have we outputted text?
+ var/hasFound = FALSE //Have we found an extract to be added?
+ for(var/obj/item/slime_extract/S in P.contents)
+ if(S.effectmod == effectmod)
+ SEND_SIGNAL(P, COMSIG_TRY_STORAGE_TAKE, S, get_turf(src), TRUE)
+ qdel(S)
+ applied++
+ hasFound = TRUE
+ if(applied >= SLIME_EXTRACT_CROSSING_REQUIRED)
+ to_chat(user, "You feed the slime as many of the extracts from the bag as you can, and it mutates!")
+ playsound(src, 'sound/effects/attackblob.ogg', 50, TRUE)
+ spawn_corecross()
+ hasOutput = TRUE
+ break
+ if(!hasOutput)
+ if(!hasFound)
+ to_chat(user, "There are no extracts in the bag that this slime will accept!")
+ else
+ to_chat(user, "You feed the slime some extracts from the bag.")
+ playsound(src, 'sound/effects/attackblob.ogg', 50, TRUE)
+ return */
+ ..()
+/*
+/mob/living/simple_animal/slime/proc/spawn_corecross()
+ var/static/list/crossbreeds = subtypesof(/obj/item/slimecross)
+ visible_message("[src] shudders, its mutated core consuming the rest of its body!")
+ playsound(src, 'sound/magic/smoke.ogg', 50, TRUE)
+ var/crosspath
+ for(var/X in crossbreeds)
+ var/obj/item/slimecross/S = X
+ if(initial(S.colour) == colour && initial(S.effect) == effectmod)
+ crosspath = S
+ break
+ if(crosspath)
+ new crosspath(loc)
+ else
+ visible_message("The mutated core shudders, and collapses into a puddle, unable to maintain its form.")
+ qdel(src)
+*/
+/mob/living/simple_animal/slime/water_act(volume, temperature, source, method = TOUCH)
+ . = ..()
+ var/water_damage = rand(10, 15) * volume
+ adjustBruteLoss(water_damage)
+ if(!client && Target && volume >= 3) // Like cats
+ Target = null
+ ++Discipline
+
+/mob/living/simple_animal/slime/examine(mob/user)
+ . = ..()
+ . += "*---------*\nThis is [bicon(src)] \a [src]!"
+ if(stat == DEAD)
+ . += "It is limp and unresponsive."
+ else
+ if(stat == UNCONSCIOUS) // Slime stasis
+ . += "It appears to be alive but unresponsive."
+ if(getBruteLoss())
+ . += ""
+ if (getBruteLoss() < 40)
+ . += "It has some punctures in its flesh!"
+ else
+ . += "It has severe punctures and tears in its flesh!"
+ . += "\n"
+
+ switch(powerlevel)
+ if(2 to 3)
+ . += "It is flickering gently with a little electrical activity."
+
+ if(4 to 5)
+ . += "It is glowing gently with moderate levels of electrical activity."
+
+ if(6 to 9)
+ . += "It is glowing brightly with high levels of electrical activity."
+
+ if(10)
+ . += "It is radiating with massive levels of electrical activity!"
+
+ . += "*---------*"
+
+/mob/living/simple_animal/slime/proc/discipline_slime(mob/user)
+ if(stat)
+ return
+
+ if(prob(80) && !client)
+ Discipline++
+
+ if(!is_adult)
+ if(Discipline == 1)
+ attacked = 0
+
+ if(Target)
+ Target = null
+ if(buckled)
+ Feedstop(silent = TRUE) //we unbuckle the slime from the mob it latched onto.
+
+ SStun = world.time + rand(20,60)
+ spawn(0)
+ canmove = FALSE
+ if(user)
+ step_away(src,user,15)
+ sleep(3)
+ if(user)
+ step_away(src,user,15)
+ update_canmove()
+
+/mob/living/simple_animal/slime/pet
+ docile = TRUE
+
+/mob/living/simple_animal/slime/can_unbuckle()
+ return FALSE
+
+/mob/living/simple_animal/slime/can_buckle()
+ return FALSE
+
+/mob/living/simple_animal/slime/get_mob_buckling_height(mob/seat)
+ if(..())
+ return 3
+
+/mob/living/simple_animal/slime/random/Initialize(mapload, new_colour, new_is_adult)
+ . = ..(mapload, pick(slime_colours), prob(50))
+
+/mob/living/simple_animal/slime/handle_ventcrawl(atom/A)
+ if(buckled)
+ to_chat(src, "I can't vent crawl while feeding...")
+ return
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/slime/subtypes.dm b/code/modules/mob/living/simple_animal/slime/subtypes.dm
similarity index 96%
rename from code/modules/mob/living/carbon/slime/subtypes.dm
rename to code/modules/mob/living/simple_animal/slime/subtypes.dm
index 35d38e31a48..b5720c62250 100644
--- a/code/modules/mob/living/carbon/slime/subtypes.dm
+++ b/code/modules/mob/living/simple_animal/slime/subtypes.dm
@@ -1,4 +1,4 @@
-proc/mutation_table(var/colour)
+/mob/living/simple_animal/slime/proc/mutation_table(colour)
var/list/slime_mutation[4]
switch(colour)
//Tier 1
@@ -76,4 +76,4 @@ proc/mutation_table(var/colour)
slime_mutation[2] = colour
slime_mutation[3] = colour
slime_mutation[4] = colour
- return(slime_mutation)
\ No newline at end of file
+ return(slime_mutation)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 4e8da45a155..c9e77e294d2 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -580,7 +580,8 @@ var/list/slot_equipment_priority = list( \
client.update_description_holders(A, is_antag)
face_atom(A)
- A.examine(src)
+ var/list/result = A.examine(src)
+ to_chat(src, result.Join("\n"))
//same as above
//note: ghosts can point, this is intended
@@ -1398,3 +1399,11 @@ var/list/slot_equipment_priority = list( \
suffix = "_8"
S.icon_state = "[initial(S.icon_state)][suffix]"
+
+///Adjust the nutrition of a mob
+/mob/proc/adjust_nutrition(change)
+ nutrition = max(0, nutrition + change)
+
+///Force set the mob nutrition
+/mob/proc/set_nutrition(change)
+ nutrition = max(0, change)
\ No newline at end of file
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 47a4e4a5d0e..ac8917398c5 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -379,6 +379,11 @@
AnnounceArrival(character, rank, join_message)
AddEmploymentContract(character)
+ if(GLOB.summon_guns_triggered)
+ give_guns(character)
+ if(GLOB.summon_magic_triggered)
+ give_magic(character)
+
if(!thisjob.is_position_available() && thisjob in SSjobs.prioritized_jobs)
SSjobs.prioritized_jobs -= thisjob
qdel(src)
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 565f5f2fd23..a03b7745d0a 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -135,41 +135,38 @@
qdel(src)
return
-/mob/living/carbon/human/proc/slimeize(adult as num, reproduce as num)
+/mob/living/carbon/human/proc/slimeize(reproduce as num)
if(notransform)
return
- for(var/obj/item/W in src)
- unEquip(W)
+ notransform = TRUE
+ canmove = FALSE
+ for(var/obj/item/I in src)
+ unEquip(I)
regenerate_icons()
- notransform = 1
- canmove = 0
icon = null
- invisibility = 101
+ invisibility = INVISIBILITY_MAXIMUM
for(var/t in bodyparts)
qdel(t)
- var/mob/living/carbon/slime/new_slime
+ var/mob/living/simple_animal/slime/new_slime
if(reproduce)
var/number = pick(14;2,3,4) //reproduce (has a small chance of producing 3 or 4 offspring)
var/list/babies = list()
for(var/i=1,i<=number,i++)
- var/mob/living/carbon/slime/M = new/mob/living/carbon/slime(loc)
- M.nutrition = round(nutrition/number)
+ var/mob/living/simple_animal/slime/M = new/mob/living/simple_animal/slime(loc)
+ M.set_nutrition(round(nutrition / number))
step_away(M,src)
babies += M
new_slime = pick(babies)
else
- new_slime = new /mob/living/carbon/slime(loc)
- if(adult)
- new_slime.is_adult = 1
- else
+ new_slime = new /mob/living/simple_animal/slime(loc)
+ new_slime.a_intent = INTENT_HARM
new_slime.key = key
to_chat(new_slime, "You are now a slime. Skreee!")
new_slime.update_pipe_vision()
- spawn(0)//To prevent the proc from returning null.
- qdel(src)
- return
+ . = new_slime
+ qdel(src)
/mob/living/carbon/human/proc/corgize()
if(notransform)
diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm
index 078cc122878..b58dfd4cc66 100644
--- a/code/modules/modular_computers/computers/item/computer.dm
+++ b/code/modules/modular_computers/computers/item/computer.dm
@@ -178,11 +178,11 @@
return 1
/obj/item/modular_computer/examine(mob/user)
- ..()
+ . = ..()
if(obj_integrity <= integrity_failure)
- to_chat(user, "It is heavily damaged!")
+ . += "It is heavily damaged!"
else if(obj_integrity < max_integrity)
- to_chat(user, "It is damaged.")
+ . += "It is damaged."
/obj/item/modular_computer/update_icon()
overlays.Cut()
diff --git a/code/modules/modular_computers/hardware/_hardware.dm b/code/modules/modular_computers/hardware/_hardware.dm
index 5549812a2e1..3e82455c53b 100644
--- a/code/modules/modular_computers/hardware/_hardware.dm
+++ b/code/modules/modular_computers/hardware/_hardware.dm
@@ -78,11 +78,11 @@
/obj/item/computer_hardware/examine(var/mob/user)
. = ..()
if(damage > damage_failure)
- to_chat(user, "It seems to be severely damaged!")
+ . += "It seems to be severely damaged!"
else if(damage > damage_malfunction)
- to_chat(user, "It seems to be damaged!")
+ . += "It seems to be damaged!"
else if(damage)
- to_chat(user, "It seems to be slightly damaged.")
+ . += "It seems to be slightly damaged."
// Component-side compatibility check.
/obj/item/computer_hardware/proc/can_install(obj/item/modular_computer/M, mob/living/user = null)
diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm
index 0c9abdf352f..1a112b248a5 100644
--- a/code/modules/modular_computers/hardware/ai_slot.dm
+++ b/code/modules/modular_computers/hardware/ai_slot.dm
@@ -16,9 +16,9 @@
/obj/item/computer_hardware/ai_slot/examine(mob/user)
- ..()
+ . = ..()
if(stored_card)
- to_chat(user, "There appears to be an intelliCard loaded. There appears to be a pinhole protecting a manual eject button. A screwdriver could probably press it")
+ . += "There appears to be an intelliCard loaded. There appears to be a pinhole protecting a manual eject button. A screwdriver could probably press it"
/obj/item/computer_hardware/ai_slot/on_install(obj/item/modular_computer/M, mob/living/user = null)
M.add_verb(device_type)
diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm
index 2872007b998..fc1abc207a5 100644
--- a/code/modules/modular_computers/hardware/card_slot.dm
+++ b/code/modules/modular_computers/hardware/card_slot.dm
@@ -107,6 +107,6 @@
return
/obj/item/computer_hardware/card_slot/examine(mob/user)
- ..()
+ . = ..()
if(stored_card || stored_card2)
- to_chat(user, "There appears to be something loaded in the card slots.")
+ . += "There appears to be something loaded in the card slots."
diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm
index 172092fd2e2..82c4aa5f62c 100644
--- a/code/modules/modular_computers/hardware/hard_drive.dm
+++ b/code/modules/modular_computers/hardware/hard_drive.dm
@@ -20,8 +20,8 @@
store_file(new/datum/computer_file/program/filemanager(src)) // File manager, allows text editor functions and basic file manipulation.
/obj/item/computer_hardware/hard_drive/examine(user)
- ..()
- to_chat(user, "It has [max_capacity] GQ of storage capacity.")
+ . = ..()
+ . += "It has [max_capacity] GQ of storage capacity."
/obj/item/computer_hardware/hard_drive/diagnostics(var/mob/user)
..()
diff --git a/code/modules/modular_computers/hardware/printer.dm b/code/modules/modular_computers/hardware/printer.dm
index 60f711ad960..0db45f33e6e 100644
--- a/code/modules/modular_computers/hardware/printer.dm
+++ b/code/modules/modular_computers/hardware/printer.dm
@@ -14,8 +14,8 @@
to_chat(user, "Paper level: [stored_paper]/[max_paper]")
/obj/item/computer_hardware/printer/examine(mob/user)
- ..()
- to_chat(user, "Paper level: [stored_paper]/[max_paper]")
+ . = ..()
+ . += "Paper level: [stored_paper]/[max_paper]"
/obj/item/computer_hardware/printer/proc/print_text(var/text_to_print, var/paper_title = "")
diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm
index be5ba9f8aed..a65610c7382 100644
--- a/code/modules/paperwork/clipboard.dm
+++ b/code/modules/paperwork/clipboard.dm
@@ -38,8 +38,9 @@
toppaper = locate(/obj/item/paper_bundle) in src
/obj/item/clipboard/examine(mob/user)
- if(..(user, 1) && toppaper)
- toppaper.examine(user)
+ . = ..()
+ if(in_range(user, src) && toppaper)
+ . += toppaper.examine(user)
obj/item/clipboard/proc/penPlacement(mob/user, obj/item/pen/P, placing)
if(placing)
diff --git a/code/modules/paperwork/frames.dm b/code/modules/paperwork/frames.dm
index 3aa4cc3d148..5270da810be 100644
--- a/code/modules/paperwork/frames.dm
+++ b/code/modules/paperwork/frames.dm
@@ -137,10 +137,10 @@
playsound(PF.loc, usesound, 100, 1)
-/obj/item/picture_frame/examine(mob/user, var/distance = -1, var/infix = "", var/suffix = "")
- ..()
+/obj/item/picture_frame/examine(mob/user, var/infix = "", var/suffix = "")
+ . = ..()
if(displayed)
- displayed.examine(user, distance, infix, suffix)
+ . += displayed.examine(user, infix, suffix)
/obj/item/picture_frame/attack_self(mob/user)
if(displayed)
@@ -245,11 +245,11 @@
else
return ..()
-/obj/structure/sign/picture_frame/examine(mob/user, var/distance = -1, var/infix = "", var/suffix = "")
+/obj/structure/sign/picture_frame/examine(mob/user, var/infix = "", var/suffix = "")
if(frame)
- frame.examine(user, distance, infix, suffix)
+ . += frame.examine(user, infix, suffix)
else
- ..()
+ . = ..()
/obj/structure/sign/picture_frame/attack_hand(mob/user)
if(frame)
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 676926153c1..ce5d51aae55 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -60,13 +60,14 @@
icon_state = "paper"
/obj/item/paper/examine(mob/user)
+ . = ..()
if(user.is_literate())
if(in_range(user, src) || istype(user, /mob/dead/observer))
show_content(user)
else
- to_chat(user, "You have to go closer if you want to read it.")
+ . += "You have to go closer if you want to read it."
else
- to_chat(user, "You don't know how to read.")
+ . += "You don't know how to read."
/obj/item/paper/proc/show_content(var/mob/user, var/forceshow = 0, var/forcestars = 0, var/infolinks = 0, var/view = 1)
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper)
diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm
index 704ec5b5819..ecc26ba0cff 100644
--- a/code/modules/paperwork/paper_bundle.dm
+++ b/code/modules/paperwork/paper_bundle.dm
@@ -100,10 +100,11 @@
to_chat(user, "You must hold \the [P] steady to burn \the [src].")
/obj/item/paper_bundle/examine(mob/user)
- if(..(user, 1))
- src.show_content(user)
+ . = ..()
+ if(in_range(user, src))
+ show_content(user)
else
- to_chat(user, "It is too far away.")
+ . += "It is too far away."
/obj/item/paper_bundle/proc/show_content(mob/user as mob)
var/dat
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index 3467a491160..68afe9fbd12 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -100,11 +100,12 @@
/obj/item/paper_bin/examine(mob/user)
- if(..(user, 1))
+ . = ..()
+ if(in_range(user, src))
if(amount)
- to_chat(usr, "There " + (amount > 1 ? "are [amount] papers" : "is one paper") + " in the bin.")
+ . += "There " + (amount > 1 ? "are [amount] papers" : "is one paper") + " in the bin."
else
- to_chat(usr, "There are no papers in the bin.")
+ . += "There are no papers in the bin."
/obj/item/paper_bin/update_icon()
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 436c4eec6fc..11beb1a7cb6 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -74,10 +74,11 @@
to_chat(user, "You must hold \the [P] steady to burn \the [src].")
/obj/item/photo/examine(mob/user)
- if(..(user, 1) || isobserver(user))
+ . = ..()
+ if(in_range(user, src) || isobserver(user))
show(user)
else
- to_chat(user, "It is too far away.")
+ . += "It is too far away."
/obj/item/photo/proc/show(mob/user as mob)
usr << browse_rsc(img, "tmp_photo.png")
@@ -539,8 +540,9 @@ var/list/SpookyGhosts = list("ghost","shade","shade2","ghost-narsie","horror","s
to_chat(user, "You switch the camera [on ? "on" : "off"].")
/obj/item/videocam/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "This video camera can send live feeds to the entertainment network. It's [camera ? "" : "in"]active.")
+ . = ..()
+ if(in_range(user, src))
+ . += "This video camera can send live feeds to the entertainment network. It's [camera ? "" : "in"]active."
/obj/item/videocam/hear_talk(mob/M as mob, list/message_pieces)
var/msg = multilingual_to_message(message_pieces)
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index f21e31a4fda..fa805f0590b 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -231,27 +231,26 @@
addtimer(CALLBACK(src, .proc/update), 5)
/obj/machinery/power/apc/examine(mob/user)
- if(..(user, 1))
+ . = ..()
+ if(in_range(user, src))
if(stat & BROKEN)
- to_chat(user, "Looks broken.")
- return
- if(opened)
+ . += "Looks broken."
+ else if(opened)
if(has_electronics && terminal)
- to_chat(user, "The cover is [opened==2?"removed":"open"] and the power cell is [ cell ? "installed" : "missing"].")
+ . += "The cover is [opened==2?"removed":"open"] and the power cell is [ cell ? "installed" : "missing"]."
else if(!has_electronics && terminal)
- to_chat(user, "There are some wires but no electronics.")
+ . += "There are some wires but no electronics."
else if(has_electronics && !terminal)
- to_chat(user, "Electronics installed but not wired.")
+ . += "Electronics installed but not wired."
else /* if(!has_electronics && !terminal) */
- to_chat(user, "There is no electronics nor connected wires.")
-
+ . += "There is no electronics nor connected wires."
else
if(stat & MAINT)
- to_chat(user, "The cover is closed. Something wrong with it: it doesn't work.")
+ . += "The cover is closed. Something wrong with it: it doesn't work."
else if(malfhack)
- to_chat(user, "The cover is broken. It may be hard to force it open.")
+ . += "The cover is broken. It may be hard to force it open."
else
- to_chat(user, "The cover is closed.")
+ . += "The cover is closed."
// update the APC icon to show the three base states
// also add overlays for indicator lights
@@ -720,7 +719,7 @@
/obj/machinery/power/apc/proc/get_malf_status(mob/living/silicon/ai/malf)
- if(istype(malf) && malf.malf_picker)
+ if(istype(malf) && malf.mind.has_antag_datum(/datum/antagonist/traitor))
if(malfai == (malf.parent || malf))
if(occupier == malf)
return 3 // 3 = User is shunted in this APC
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 68eaec16040..198c5f64356 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -595,15 +595,14 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
w_class = WEIGHT_CLASS_SMALL
/obj/item/stack/cable_coil/examine(mob/user)
- if(!..(user, 1))
- return
-
- if(get_amount() == 1)
- to_chat(user, "A short piece of power cable.")
- else if(get_amount() == 2)
- to_chat(user, "A piece of power cable.")
- else
- to_chat(user, "A coil of power cable. There are [get_amount()] lengths of cable in the coil.")
+ . = ..()
+ if(in_range(user, src))
+ if(get_amount() == 1)
+ . += "A short piece of power cable."
+ else if(get_amount() == 2)
+ . += "A piece of power cable."
+ else
+ . += "A coil of power cable. There are [get_amount()] lengths of cable in the coil."
// Items usable on a cable coil :
// - Wirecutters : cut them duh !
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 8bc8b538640..3118363727f 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -85,11 +85,11 @@
return power_used
/obj/item/stock_parts/cell/examine(mob/user)
- ..()
+ . = ..()
if(rigged)
- to_chat(user, "This power cell seems to be faulty!")
+ . += "This power cell seems to be faulty!"
else
- to_chat(user, "The charge meter reads [round(percent() )]%.")
+ . += "The charge meter reads [round(percent() )]%."
/obj/item/stock_parts/cell/suicide_act(mob/user)
to_chat(viewers(user), "[user] is licking the electrodes of the [src]! It looks like [user.p_theyre()] trying to commit suicide.")
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index bb3cdb2a37c..98c7f2e8e51 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -28,14 +28,15 @@
icon_state = "bulb-construct-stage1"
/obj/machinery/light_construct/examine(mob/user)
- if(..(user, 2))
- switch(src.stage)
+ . = ..()
+ if(get_dist(user, src) <= 2)
+ switch(stage)
if(1)
- to_chat(usr, "It's an empty frame.")
+ . += "It's an empty frame."
if(2)
- to_chat(usr, "It's wired.")
+ . += "It's wired."
if(3)
- to_chat(usr, "The casing is closed.")
+ . += "The casing is closed."
/obj/machinery/light_construct/attackby(obj/item/W as obj, mob/living/user as mob, params)
src.add_fingerprint(user)
@@ -288,16 +289,17 @@
// examine verb
/obj/machinery/light/examine(mob/user)
- if(..(user, 1))
+ . = ..()
+ if(in_range(user, src))
switch(status)
if(LIGHT_OK)
- to_chat(user, "[desc] It is turned [on? "on" : "off"].")
+ . += "[desc] It is turned [on? "on" : "off"]."
if(LIGHT_EMPTY)
- to_chat(user, "[desc] The [fitting] has been removed.")
+ . += "[desc] The [fitting] has been removed."
if(LIGHT_BURNED)
- to_chat(user, "[desc] The [fitting] is burnt out.")
+ . += "[desc] The [fitting] is burnt out."
if(LIGHT_BROKEN)
- to_chat(user, "[desc] The [fitting] has been smashed.")
+ . += "[desc] The [fitting] has been smashed."
diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm
index bf2563fe310..203fbd9b734 100644
--- a/code/modules/power/port_gen.dm
+++ b/code/modules/power/port_gen.dm
@@ -52,12 +52,12 @@
return
/obj/machinery/power/port_gen/examine(mob/user)
- if(!..(user,1 ))
- return
- if(active)
- to_chat(usr, "The generator is on.")
- else
- to_chat(usr, "The generator is off.")
+ . = ..()
+ if(!in_range(user, src))
+ if(active)
+ . += "The generator is on."
+ else
+ . += "The generator is off."
/obj/machinery/power/port_gen/emp_act(severity)
var/duration = 6000 //ten minutes
@@ -154,13 +154,13 @@
power_gen = round(initial(power_gen) * (max(2, temp_rating) / 2))
/obj/machinery/power/port_gen/pacman/examine(mob/user)
- ..(user)
- to_chat(user, "\The [src] appears to be producing [power_gen*power_output] W.")
- to_chat(user, "There [sheets == 1 ? "is" : "are"] [sheets] sheet\s left in the hopper.")
+ . = ..()
+ . += "\The [src] appears to be producing [power_gen*power_output] W."
+ . += "There [sheets == 1 ? "is" : "are"] [sheets] sheet\s left in the hopper."
if(IsBroken())
- to_chat(user, "\The [src] seems to have broken down.")
+ . += "\The [src] seems to have broken down."
if(overheating)
- to_chat(user, "\The [src] is overheating!")
+ . += "\The [src] is overheating!"
/obj/machinery/power/port_gen/pacman/HasFuel()
var/needed_sheets = power_output / time_per_sheet
diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm
index 32d4160847b..60adf9b2fc3 100644
--- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm
@@ -133,7 +133,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin
desc = text("The [name] is assembled")
if(powered)
desc = desc_holder
- ..(user)
+ . = ..()
/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user, params)
if(istool(W))
diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm
index 19948c94a36..754479a69ca 100644
--- a/code/modules/power/tesla/energy_ball.dm
+++ b/code/modules/power/tesla/energy_ball.dm
@@ -57,9 +57,10 @@
energy = 0 // ensure we dont have miniballs of miniballs
/obj/singularity/energy_ball/examine(mob/user)
- ..()
- if(orbiting_balls.len)
- to_chat(user, "The amount of orbiting mini-balls is [orbiting_balls.len].")
+ . = ..()
+ var/len = LAZYLEN(orbiting_balls)
+ if(len)
+ . += "The amount of orbiting mini-balls is [len]."
/obj/singularity/energy_ball/proc/move_the_basket_ball(var/move_amount)
diff --git a/code/modules/power/treadmill.dm b/code/modules/power/treadmill.dm
index 36f3ac15df4..5a1cc12c701 100644
--- a/code/modules/power/treadmill.dm
+++ b/code/modules/power/treadmill.dm
@@ -168,8 +168,8 @@
update_icon()
/obj/machinery/treadmill_monitor/examine(mob/user)
- ..()
- to_chat(user, "The display reads:[line1]
[line2]
")
+ . = ..()
+ . += "The display reads:[line1]
[line2]
"
/obj/machinery/treadmill_monitor/update_icon()
overlays.Cut()
diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm
index bf6df41006a..2f422e227b3 100644
--- a/code/modules/projectiles/ammunition/magazines.dm
+++ b/code/modules/projectiles/ammunition/magazines.dm
@@ -236,10 +236,10 @@
if(ammo && is_rubber())
overlays += image('icons/obj/ammo.dmi', icon_state = "enforcer-r")
-/obj/item/ammo_box/magazine/enforcer/examine(mob/user, var/distance)
- ..()
- if(distance <= 2)
- to_chat(user, "It seems to be loaded with [is_rubber() ? "rubber" : "lethal"] bullets.")//only can see the topmost one.
+/obj/item/ammo_box/magazine/enforcer/examine(mob/user)
+ . = ..()
+ if(get_dist(user, src) <= 2)
+ . += "It seems to be loaded with [is_rubber() ? "rubber" : "lethal"] bullets."//only can see the topmost one.
/obj/item/ammo_box/magazine/enforcer/proc/is_rubber()//if the topmost bullet is a rubber one
var/ammo = ammo_count()
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index fbc29da0391..510e8f60264 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -85,17 +85,17 @@
return ..()
/obj/item/gun/examine(mob/user)
- ..()
+ . = ..()
if(unique_reskin && !current_skin)
- to_chat(user, "Alt-click it to reskin it.")
+ . += "Alt-click it to reskin it."
if(unique_rename)
- to_chat(user, "Use a pen on it to rename it.")
+ . += "Use a pen on it to rename it."
if(bayonet)
- to_chat(user, "It has \a [bayonet] [can_bayonet ? "" : "permanently "]affixed to it.")
+ . += "It has \a [bayonet] [can_bayonet ? "" : "permanently "]affixed to it."
if(can_bayonet) //if it has a bayonet and this is false, the bayonet is permanent.
- to_chat(user, "[bayonet] looks like it can be unscrewed from [src].")
+ . += "[bayonet] looks like it can be unscrewed from [src]."
else if(can_bayonet)
- to_chat(user, "It has a bayonet lug on it.")
+ . += "It has a bayonet lug on it."
/obj/item/gun/proc/process_chamber()
return 0
diff --git a/code/modules/projectiles/guns/dartgun.dm b/code/modules/projectiles/guns/dartgun.dm
index 97f4eaebf1c..0a50b844f4a 100644
--- a/code/modules/projectiles/guns/dartgun.dm
+++ b/code/modules/projectiles/guns/dartgun.dm
@@ -56,13 +56,14 @@
update_icon()
/obj/item/gun/dartgun/examine(mob/user)
- if(..(user, 2))
+ . = ..()
+ if(get_dist(user, src) <= 2)
if(beakers.len)
- to_chat(user, "[src] contains:")
+ . += "[src] contains:"
for(var/obj/item/reagent_containers/glass/beaker/B in beakers)
if(B.reagents && B.reagents.reagent_list.len)
for(var/datum/reagent/R in B.reagents.reagent_list)
- to_chat(user, "[R.volume] units of [R.name]")
+ . += "[R.volume] units of [R.name]"
/obj/item/gun/dartgun/attackby(obj/item/I as obj, mob/user as mob, params)
if(istype(I, /obj/item/dart_cartridge))
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index 9c1ea1a7a9f..f64cba9632c 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -28,12 +28,13 @@
var/empty_state = "kineticgun_empty"
/obj/item/gun/energy/kinetic_accelerator/examine(mob/user)
- if(..(user, 1))
+ . = ..()
+ if(in_range(user, src))
if(max_mod_capacity)
- to_chat(user, "[get_remaining_mod_capacity()]% mod capacity remaining.")
+ . += "[get_remaining_mod_capacity()]% mod capacity remaining."
for(var/A in get_modkits())
var/obj/item/borg/upgrade/modkit/M = A
- to_chat(user, "There is a [M.name] mod installed, using [M.cost]% capacity.")
+ . += "There is a [M.name] mod installed, using [M.cost]% capacity."
/obj/item/gun/energy/kinetic_accelerator/attackby(obj/item/I, mob/user)
if(iscrowbar(I))
@@ -257,8 +258,9 @@
var/minebot_exclusive = FALSE
/obj/item/borg/upgrade/modkit/examine(mob/user)
- if(..(user, 1))
- to_chat(user, "Occupies [cost]% of mod capacity.")
+ . = ..()
+ if(in_range(user, src))
+ . += "Occupies [cost]% of mod capacity."
/obj/item/borg/upgrade/modkit/attackby(obj/item/A, mob/user)
if(istype(A, /obj/item/gun/energy/kinetic_accelerator) && !issilicon(user))
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index d51f9446b49..5a9e87aa119 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -159,9 +159,9 @@
can_charge = 0
/obj/item/gun/energy/plasmacutter/examine(mob/user)
- ..()
+ . = ..()
if(power_supply)
- to_chat(user, "[src] is [round(power_supply.percent())]% charged.")
+ . += "[src] is [round(power_supply.percent())]% charged."
/obj/item/gun/energy/plasmacutter/attackby(obj/item/A, mob/user)
if(istype(A, /obj/item/stack/sheet/mineral/plasma))
diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/grenade_launcher.dm
index 81b8451eb77..af7cffbe7c8 100644
--- a/code/modules/projectiles/guns/grenade_launcher.dm
+++ b/code/modules/projectiles/guns/grenade_launcher.dm
@@ -14,8 +14,9 @@
materials = list(MAT_METAL=2000)
/obj/item/gun/grenadelauncher/examine(mob/user)
- if(..(user, 2))
- to_chat(user, "[grenades.len] / [max_grenades] grenades.")
+ . = ..()
+ if(get_dist(user, src) <= 2)
+ . += "[grenades.len] / [max_grenades] grenades."
/obj/item/gun/grenadelauncher/attackby(obj/item/I as obj, mob/user as mob, params)
if((istype(I, /obj/item/grenade)))
diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm
index 1a5ecc178d1..544ca67a361 100644
--- a/code/modules/projectiles/guns/magic/wand.dm
+++ b/code/modules/projectiles/guns/magic/wand.dm
@@ -18,8 +18,8 @@
..()
/obj/item/gun/magic/wand/examine(mob/user)
- ..()
- to_chat(user, "Has [charges] charge\s remaining.")
+ . = ..()
+ . += "Has [charges] charge\s remaining."
/obj/item/gun/magic/wand/update_icon()
icon_state = "[initial(icon_state)][charges ? "" : "-drained"]"
diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm
index 15efee700d2..133331f8e44 100644
--- a/code/modules/projectiles/guns/projectile.dm
+++ b/code/modules/projectiles/guns/projectile.dm
@@ -149,8 +149,8 @@
return
/obj/item/gun/projectile/examine(mob/user)
- ..()
- to_chat(user, "Has [get_ammo()] round\s remaining.")
+ . = ..()
+ . += "Has [get_ammo()] round\s remaining."
/obj/item/gun/projectile/proc/get_ammo(countchambered = 1)
var/boolets = 0 //mature var names for mature people
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 6f977f2e024..99ec51f9fdd 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -84,8 +84,8 @@
return boolets
/obj/item/gun/projectile/revolver/examine(mob/user)
- ..()
- to_chat(user, "[get_ammo(0,0)] of those are live rounds.")
+ . = ..()
+ . += "[get_ammo(0,0)] of those are live rounds."
/obj/item/gun/projectile/revolver/detective
desc = "A cheap Martian knock-off of a classic law enforcement firearm. Uses .38-special rounds."
@@ -467,7 +467,7 @@
f_name = "a "
f_name += "blood-stained [name]!"
- to_chat(user, "[bicon(src)] That's [f_name]")
+ . = list("[bicon(src)] That's [f_name]")
if(desc)
- to_chat(user, desc)
+ . += desc
diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm
index 8b658911b3b..ee6b013af0d 100644
--- a/code/modules/projectiles/guns/projectile/shotgun.dm
+++ b/code/modules/projectiles/guns/projectile/shotgun.dm
@@ -66,9 +66,9 @@
chambered = AC
/obj/item/gun/projectile/shotgun/examine(mob/user)
- ..()
+ . = ..()
if(chambered)
- to_chat(user, "A [chambered.BB ? "live" : "spent"] one is in the chamber.")
+ . += "A [chambered.BB ? "live" : "spent"] one is in the chamber."
/obj/item/gun/projectile/shotgun/isHandgun() //You cannot, in fact, holster a shotgun.
return 0
@@ -239,8 +239,8 @@
. = ..()
/obj/item/gun/projectile/shotgun/boltaction/examine(mob/user)
- ..()
- to_chat(user, "The bolt is [bolt_open ? "open" : "closed"].")
+ . = ..()
+ . += "The bolt is [bolt_open ? "open" : "closed"]."
/obj/item/gun/projectile/shotgun/boltaction/enchanted
name = "enchanted bolt action rifle"
diff --git a/code/modules/projectiles/guns/rocket.dm b/code/modules/projectiles/guns/rocket.dm
index 983c6f319fd..53de1a16854 100644
--- a/code/modules/projectiles/guns/rocket.dm
+++ b/code/modules/projectiles/guns/rocket.dm
@@ -16,8 +16,8 @@
var/list/rockets = new/list()
/obj/item/gun/rocketlauncher/examine(mob/user)
- ..()
- to_chat(user, "[rockets.len] / [max_rockets] rockets.")
+ . = ..()
+ . += "[rockets.len] / [max_rockets] rockets."
/obj/item/gun/rocketlauncher/Destroy()
QDEL_LIST(rockets)
diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm
index ca18cdcd82e..04cf2d248d3 100644
--- a/code/modules/projectiles/guns/syringe_gun.dm
+++ b/code/modules/projectiles/guns/syringe_gun.dm
@@ -46,8 +46,8 @@
..()
/obj/item/gun/syringe/examine(mob/user)
- ..()
- to_chat(user, "Can hold [max_syringes] syringe\s. Has [syringes.len] syringe\s remaining.")
+ . = ..()
+ . += "Can hold [max_syringes] syringe\s. Has [syringes.len] syringe\s remaining."
/obj/item/gun/syringe/attack_self(mob/living/user as mob)
if(!syringes.len)
diff --git a/code/modules/projectiles/guns/throw.dm b/code/modules/projectiles/guns/throw.dm
index 97bb65f5d02..58f3db026e1 100644
--- a/code/modules/projectiles/guns/throw.dm
+++ b/code/modules/projectiles/guns/throw.dm
@@ -12,7 +12,7 @@
var/projectile_speed = 1
var/projectile_range = 1
-/obj/item/gun/throw/proc/notify_ammo_count(mob/user)
+/obj/item/gun/throw/proc/notify_ammo_count()
return
/obj/item/gun/throw/proc/get_throwrange()
@@ -31,9 +31,9 @@
return count
/obj/item/gun/throw/examine(mob/user)
- ..()
- to_chat(user, "It is [to_launch ? "loaded with \a [to_launch]" : "not loaded"].")
- notify_ammo_count(user)
+ . = ..()
+ . += "It is [to_launch ? "loaded with \a [to_launch]" : "not loaded"]."
+ . += notify_ammo_count()
/obj/item/gun/throw/Destroy()
QDEL_NULL(to_launch)
@@ -53,7 +53,7 @@
to_chat(user, "You load [I] into [src].")
if(!to_launch)
process_chamber()
- notify_ammo_count(user)
+ to_chat(user, notify_ammo_count())
else
to_chat(user, "[src] cannot hold any more projectiles.")
else
diff --git a/code/modules/projectiles/guns/throw/crossbow.dm b/code/modules/projectiles/guns/throw/crossbow.dm
index 9c87f7949a9..ca626534320 100644
--- a/code/modules/projectiles/guns/throw/crossbow.dm
+++ b/code/modules/projectiles/guns/throw/crossbow.dm
@@ -39,11 +39,11 @@
icon_state = "[initial(icon_state)]-drawn"
/obj/item/gun/throw/crossbow/examine(mob/user)
- ..()
+ . = ..()
if(cell)
- to_chat(user, "\A [cell] is mounted onto [src]. Battery cell charge: [cell.charge]/[cell.maxcharge]")
+ . += "\A [cell] is mounted onto [src]. Battery cell charge: [cell.charge]/[cell.maxcharge]"
else
- to_chat(user, "It has an empty mount for a battery cell.")
+ . += "It has an empty mount for a battery cell."
/obj/item/gun/throw/crossbow/modify_projectile(obj/item/I, on_chamber = 0)
if(cell && on_chamber && istype(I, /obj/item/arrow/rod))
diff --git a/code/modules/projectiles/guns/throw/pielauncher.dm b/code/modules/projectiles/guns/throw/pielauncher.dm
index ed3a70ad032..69dcc166aae 100644
--- a/code/modules/projectiles/guns/throw/pielauncher.dm
+++ b/code/modules/projectiles/guns/throw/pielauncher.dm
@@ -21,8 +21,8 @@
loaded_projectiles += P
process_chamber()
-/obj/item/gun/throw/piecannon/notify_ammo_count(mob/user)
- to_chat(user, "[src] has [get_ammocount()] of [max_capacity] pies left.")
+/obj/item/gun/throw/piecannon/notify_ammo_count()
+ return "[src] has [get_ammocount()] of [max_capacity] pies left."
/obj/item/gun/throw/piecannon/update_icon()
if(to_launch)
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 4bf6c98fc50..76d7c513bcc 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -202,7 +202,7 @@
if(ishuman(M))
Robot.mmi.transfer_identity(M) //Does not transfer key/client.
if("slime")
- new_mob = new /mob/living/carbon/slime/random(M.loc)
+ new_mob = new /mob/living/simple_animal/slime/random(M.loc)
new_mob.universal_speak = TRUE
if("xeno")
if(prob(50))
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index 41646c114af..06ab5c9a61b 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -171,7 +171,7 @@
if(ishuman(target)) //These rays make plantmen fat.
var/mob/living/carbon/human/H = M
if(IS_PLANT in H.dna.species.species_traits)
- H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL)
+ H.set_nutrition(min(H.nutrition+30, NUTRITION_LEVEL_FULL))
else if(iscarbon(target))
M.show_message("The radiation beam dissipates harmlessly through your body.")
else
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index 331e5d9ca8f..b594743baef 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -74,6 +74,18 @@ var/const/INGEST = 2
handle_reactions()
return total_transfered
+/datum/reagents/proc/remove_all(amount = 1)
+ var/list/cached_reagents = reagent_list
+ if(total_volume > 0)
+ var/part = amount / total_volume
+ for(var/reagent in cached_reagents)
+ var/datum/reagent/R = reagent
+ remove_reagent(R.id, R.volume * part)
+
+ update_total()
+ handle_reactions()
+ return amount
+
/datum/reagents/proc/get_master_reagent()
var/the_reagent = null
var/the_volume = 0
@@ -803,7 +815,7 @@ var/const/INGEST = 2
if(!R.taste_mult)
continue
//nutriment carries a list of tastes that originates from the snack food that the nutriment came from
- if(istype(R, /datum/reagent/consumable/nutriment))
+ if(istype(R, /datum/reagent/consumable/nutriment))
var/list/nutriment_taste_data = R.data
for(var/nutriment_taste in nutriment_taste_data)
var/ratio = nutriment_taste_data[nutriment_taste]
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index f3788fed093..e382fb93f3d 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -106,11 +106,11 @@
return ..()
/obj/machinery/chem_dispenser/examine(mob/user)
- ..()
+ . = ..()
if(panel_open)
- to_chat(user, "[src]'s maintenance hatch is open!")
+ . += "[src]'s maintenance hatch is open!"
if(in_range(user, src) || isobserver(user))
- to_chat(user, "The status display reads:
Recharging [recharge_amount] power units per interval.
Power efficiency increased by [round((powerefficiency * 1000) - 100, 1)]%.")
+ . += "The status display reads:
Recharging [recharge_amount] power units per interval.
Power efficiency increased by [round((powerefficiency * 1000) - 100, 1)]%."
/obj/machinery/chem_dispenser/process()
diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm
index 4d6303f490c..5353dc54b88 100644
--- a/code/modules/reagents/chemistry/reagents/food.dm
+++ b/code/modules/reagents/chemistry/reagents/food.dm
@@ -16,7 +16,7 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.can_eat(diet_flags)) //Make sure the species has it's dietflag set, otherwise it can't digest any nutrients
- H.nutrition += nutriment_factor // For hunger and fatness
+ H.adjust_nutrition(nutriment_factor) // For hunger and fatness
return ..()
/datum/reagent/consumable/nutriment // Pure nutriment, universally digestable and thus slightly less effective
@@ -279,8 +279,8 @@
/datum/reagent/consumable/frostoil/reaction_turf(turf/T, volume)
if(volume >= 5)
- for(var/mob/living/carbon/slime/M in T)
- M.adjustToxLoss(rand(15,30))
+ for(var/mob/living/simple_animal/slime/M in T)
+ M.adjustToxLoss(rand(15, 30))
/datum/reagent/consumable/sodiumchloride
name = "Salt"
@@ -838,13 +838,16 @@
color = "#63DE63"
taste_description = "burned food"
-/datum/reagent/questionmark/reaction_mob(mob/living/M, method=TOUCH, volume)
- if(method == INGEST)
- M.Stun(2, FALSE)
- M.Weaken(2, FALSE)
- M.update_canmove()
- to_chat(M, "Ugh! Eating that was a terrible idea!")
- M.ForceContractDisease(new /datum/disease/food_poisoning(0))
+/datum/reagent/questionmark/reaction_mob(mob/living/carbon/human/H, method = TOUCH, volume)
+ if(istype(H) && method == INGEST)
+ if(H.dna.species.taste_sensitivity < TASTE_SENSITIVITY_NO_TASTE) // If you can taste it, then you know how awful it is.
+ H.Stun(2, FALSE)
+ H.Weaken(2, FALSE)
+ H.update_canmove()
+ to_chat(H, "Ugh! Eating that was a terrible idea!")
+ if(NO_HUNGER in H.dna.species.species_traits) //If you don't eat, then you can't get food poisoning
+ return
+ H.ForceContractDisease(new /datum/disease/food_poisoning(0))
/datum/reagent/msg
name = "Monosodium glutamate"
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm
index a01c034a4ae..17eee91080e 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm
@@ -356,7 +356,7 @@
if(volume >= 3)
T.MakeSlippery(TURF_WET_ICE)
if(volume >= 5)
- for(var/mob/living/carbon/slime/M in T)
+ for(var/mob/living/simple_animal/slime/M in T)
M.adjustToxLoss(rand(15,30))
/datum/reagent/pyrosium
diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm
index 2b2c2b2cdf9..b8ccede11bd 100644
--- a/code/modules/reagents/chemistry/reagents/toxins.dm
+++ b/code/modules/reagents/chemistry/reagents/toxins.dm
@@ -868,8 +868,8 @@
to_chat(M, "Your stomach grumbles painfully!")
else
if(prob(60))
- var/fat_to_burn = max(round(M.nutrition/100,1), 5)
- M.nutrition = max(0, M.nutrition-fat_to_burn)
+ var/fat_to_burn = max(round(M.nutrition / 100, 1), 5)
+ M.adjust_nutrition(-fat_to_burn)
M.overeatduration = 0
return ..() | update_flags
diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm
index 76ae7f49d9f..0ac02087763 100644
--- a/code/modules/reagents/chemistry/reagents/water.dm
+++ b/code/modules/reagents/chemistry/reagents/water.dm
@@ -80,8 +80,8 @@
if(floor_only)
T.clean_blood()
- for(var/mob/living/carbon/slime/M in T)
- M.adjustToxLoss(rand(5,10))
+ for(var/mob/living/simple_animal/slime/M in T)
+ M.adjustToxLoss(rand(5, 10))
if(istype(T, /turf/simulated))
var/turf/simulated/S = T
S.dirt = 0
diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
index a1e96ea35f5..1767d3964a1 100644
--- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm
+++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
@@ -11,9 +11,8 @@
/datum/chemical_reaction/slimespawn/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
- var/mob/living/carbon/slime/S = new /mob/living/carbon/slime
- S.forceMove(get_turf(holder.my_atom))
- S.visible_message("Infused with plasma, the core begins to quiver and grow, and soon a new baby slime emerges from it!")
+ var/mob/living/simple_animal/slime/S = new(get_turf(holder.my_atom), "grey")
+ S.visible_message("Infused with plasma, the core begins to quiver and grow, and a new baby slime emerges from it!")
/datum/chemical_reaction/slimeinaprov
name = "Slime epinephrine"
@@ -425,7 +424,12 @@
/datum/chemical_reaction/slimebloodlust/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
- for(var/mob/living/carbon/slime/slime in viewers(get_turf(holder.my_atom), null))
+ for(var/mob/living/simple_animal/slime/slime in viewers(get_turf(holder.my_atom), null))
+ if(slime.docile) //Undoes docility, but doesn't make rabid.
+ slime.visible_message("[slime] forgets its training, becoming wild once again!")
+ slime.docile = FALSE
+ slime.update_name()
+ continue
slime.rabid = 1
slime.visible_message("The [slime] is driven into a frenzy!")
@@ -667,9 +671,8 @@
/datum/chemical_reaction/slimeRNG/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
- var/mob/living/carbon/slime/random/S = new /mob/living/carbon/slime/random
- S.forceMove(get_turf(holder.my_atom))
- S.visible_message("Infused with plasma, the core begins to quiver and grow, and soon a new baby slime emerges from it!")
+ var/mob/living/simple_animal/slime/random/S = new (get_turf(holder.my_atom))
+ S.visible_message("Infused with plasma, the core begins to quiver and grow, and a new baby slime emerges from it!")
/datum/chemical_reaction/slime_transfer
name = "Transfer Potion"
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index e15e6316cb1..fa86a25f11c 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -102,16 +102,15 @@
return
/obj/item/reagent_containers/borghypo/examine(mob/user)
- if(!..(user, 2))
- return
+ . = ..()
+ if(get_dist(user, src) <= 2)
+ var/empty = TRUE
- var/empty = 1
+ for(var/datum/reagents/RS in reagent_list)
+ var/datum/reagent/R = locate() in RS.reagent_list
+ if(R)
+ . += "It currently has [R.volume] units of [R.name] stored."
+ empty = FALSE
- for(var/datum/reagents/RS in reagent_list)
- var/datum/reagent/R = locate() in RS.reagent_list
- if(R)
- to_chat(user, "It currently has [R.volume] units of [R.name] stored.")
- empty = 0
-
- if(empty)
- to_chat(user, "It is currently empty. Allow some time for the internal syntheszier to produce more.")
+ if(empty)
+ . += "It is currently empty. Allow some time for the internal syntheszier to produce more."
diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm
index e9bad3c912d..0114a7bdc76 100644
--- a/code/modules/reagents/reagent_containers/glass_containers.dm
+++ b/code/modules/reagents/reagent_containers/glass_containers.dm
@@ -52,10 +52,9 @@
base_name = name
/obj/item/reagent_containers/glass/examine(mob/user)
- if(!..(user, 2))
- return
- if(!is_open_container())
- to_chat(user, "Airtight lid seals it completely.")
+ . = ..()
+ if(get_dist(user, src) <= 2 && !is_open_container())
+ . += "Airtight lid seals it completely."
/obj/item/reagent_containers/glass/attack(mob/M, mob/user, def_zone)
if(!is_open_container())
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index be184753f14..aa6d8b99cd9 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -124,11 +124,11 @@
icon_state = "[initial(icon_state)]0"
/obj/item/reagent_containers/hypospray/autoinjector/examine()
- ..()
+ . = ..()
if(reagents && reagents.reagent_list.len)
- to_chat(usr, "It is currently loaded.")
+ . += "It is currently loaded."
else
- to_chat(usr, "It is spent.")
+ . += "It is spent."
/obj/item/reagent_containers/hypospray/autoinjector/teporone //basilisks
name = "teporone autoinjector"
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index d8ee5d88309..482b8b20ccd 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -83,8 +83,9 @@
to_chat(user, "You [amount_per_transfer_from_this == 10 ? "remove" : "fix"] the nozzle. You'll now use [amount_per_transfer_from_this] units per spray.")
/obj/item/reagent_containers/spray/examine(mob/user)
- if(..(user, 0) && user == loc)
- to_chat(user, "[round(reagents.total_volume)] units left.")
+ . = ..()
+ if(get_dist(user, src) && user == loc)
+ . += "[round(reagents.total_volume)] units left."
/obj/item/reagent_containers/spray/verb/empty()
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index 5940bc35c21..964375a6668 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -117,10 +117,9 @@
boom()
/obj/structure/reagent_dispensers/fueltank/examine(mob/user)
- if(!..(user, 2))
- return
- if(rig)
- to_chat(usr, "There is some kind of device rigged to the tank.")
+ . = ..()
+ if(get_dist(user, src) <= 2 && rig)
+ . += "There is some kind of device rigged to the tank."
/obj/structure/reagent_dispensers/fueltank/attack_hand()
if(rig)
@@ -225,9 +224,9 @@
var/paper_cups = 25 //Paper cups left from the cooler
/obj/structure/reagent_dispensers/water_cooler/examine(mob/user)
- if(!..(user, 2))
- return
- to_chat(user, "There are [paper_cups ? paper_cups : "no"] paper cups left.")
+ . = ..()
+ if(get_dist(user, src) <= 2)
+ . += "There are [paper_cups ? paper_cups : "no"] paper cups left."
/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user)
if(!paper_cups)
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index 27a90589eec..11cd0e743e6 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -181,7 +181,7 @@
// mouse drop another mob or self
//
/obj/machinery/disposal/MouseDrop_T(mob/target, mob/user)
- if(!istype(target) || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || istype(user, /mob/living/silicon/ai))
+ if(!istype(target) || target.buckled || target.has_buckled_mobs() || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || istype(user, /mob/living/silicon/ai))
return
if(isanimal(user) && target != user) return //animals cannot put mobs other than themselves into disposal
src.add_fingerprint(user)
diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm
index 785c03b13a1..f6df6ece19b 100644
--- a/code/modules/research/xenobiology/xenobio_camera.dm
+++ b/code/modules/research/xenobiology/xenobio_camera.dm
@@ -48,7 +48,7 @@
/obj/machinery/computer/camera_advanced/xenobio/Destroy()
QDEL_NULL(current_potion)
- for(var/mob/living/carbon/slime/S in stored_slimes)
+ for(var/mob/living/simple_animal/slime/S in stored_slimes)
S.forceMove(drop_location())
stored_slimes.Cut()
return ..()
@@ -173,7 +173,7 @@
var/obj/machinery/computer/camera_advanced/xenobio/X = target
if(cameranet.checkTurfVis(remote_eye.loc))
- for(var/mob/living/carbon/slime/S in X.stored_slimes)
+ for(var/mob/living/simple_animal/slime/S in X.stored_slimes)
S.forceMove(remote_eye.loc)
S.visible_message("[S] warps in!")
X.stored_slimes -= S
@@ -192,14 +192,13 @@
var/obj/machinery/computer/camera_advanced/xenobio/X = target
if(cameranet.checkTurfVis(remote_eye.loc))
- for(var/mob/living/carbon/slime/S in remote_eye.loc)
+ for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
if(X.stored_slimes.len >= X.max_slimes)
break
if(!S.ckey)
if(S.buckled)
- S.buckled.unbuckle_mob(S, force = TRUE)
- S.Feedstop()
- S.visible_message("[S] vanishes in a flash of light!")
+ S.Feedstop(silent = TRUE)
+ S.visible_message("[S] vanishes in a flash of light!")
S.forceMove(X)
X.stored_slimes += S
else
@@ -265,7 +264,7 @@
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
if(cameranet.checkTurfVis(remote_eye.loc))
- for(var/mob/living/carbon/slime/S in remote_eye.loc)
+ for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
slime_scan(S, C)
else
to_chat(owner, "Target is not near a camera. Cannot proceed.")
@@ -287,7 +286,7 @@
return
if(cameranet.checkTurfVis(remote_eye.loc))
- for(var/mob/living/carbon/slime/S in remote_eye.loc)
+ for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
X.current_potion.attack(S, C)
break
else
@@ -310,17 +309,17 @@
// Alternate clicks for slime, monkey and open turf if using a xenobio console
// Scans slime
-/mob/living/carbon/slime/CtrlClick(mob/user)
+/mob/living/simple_animal/slime/CtrlClick(mob/user)
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_CTRL, src)
..()
//Feeds a potion to slime
-/mob/living/carbon/slime/AltClick(mob/user)
+/mob/living/simple_animal/slime/AltClick(mob/user)
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_ALT, src)
..()
//Picks up slime
-/mob/living/carbon/slime/ShiftClick(mob/user)
+/mob/living/simple_animal/slime/ShiftClick(mob/user)
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_SHIFT, src)
..()
@@ -341,7 +340,7 @@
..()
// Scans slime
-/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickCtrl(mob/living/user, mob/living/carbon/slime/S)
+/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickCtrl(mob/living/user, mob/living/simple_animal/slime/S)
if(!cameranet.checkTurfVis(S.loc))
to_chat(user, "Target is not near a camera. Cannot proceed.")
return
@@ -352,7 +351,7 @@
slime_scan(S, C)
//Feeds a potion to slime
-/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/carbon/slime/S)
+/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/simple_animal/slime/S)
if(!cameranet.checkTurfVis(S.loc))
to_chat(user, "Target is not near a camera. Cannot proceed.")
return
@@ -367,7 +366,7 @@
X.current_potion.attack(S, C)
//Picks up slime
-/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickShift(mob/living/user, mob/living/carbon/slime/S)
+/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickShift(mob/living/user, mob/living/simple_animal/slime/S)
if(!cameranet.checkTurfVis(S.loc))
to_chat(user, "Target is not near a camera. Cannot proceed.")
return
@@ -377,14 +376,16 @@
var/area/mobarea = get_area(S.loc)
if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible)
if(X.stored_slimes.len >= X.max_slimes)
+ to_chat(C, "Slime storage is full.")
return
- if(!S.ckey)
- if(S.buckled)
- S.buckled.unbuckle_mob(S, force = TRUE)
- S.Feedstop()
- S.visible_message("[S] vanishes in a flash of light!")
- S.forceMove(X)
- X.stored_slimes += S
+ if(S.ckey)
+ to_chat(C, "The slime wiggled free!")
+ return
+ if(S.buckled)
+ S.Feedstop(silent = TRUE)
+ S.visible_message("[S] vanishes in a flash of light!")
+ S.forceMove(X)
+ X.stored_slimes += S
//Place slimes
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickShift(mob/living/user, turf/T)
@@ -396,9 +397,9 @@
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
var/area/turfarea = get_area(T)
if(turfarea.name == E.allowed_area || turfarea.xenobiology_compatible)
- for(var/mob/living/carbon/slime/S in X.stored_slimes)
+ for(var/mob/living/simple_animal/slime/S in X.stored_slimes)
S.forceMove(T)
- S.visible_message("[S] warps in!")
+ S.visible_message("[S] warps in!")
X.stored_slimes -= S
//Place monkey
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index d3c2740b7f6..c594e08b3b3 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -139,7 +139,7 @@
icon_state = "bottle19"
var/being_used = 0
-/obj/item/slimepotion/slime/docility/attack(mob/living/carbon/slime/M, mob/user)
+/obj/item/slimepotion/slime/docility/attack(mob/living/simple_animal/slime/M, mob/user)
if(!isslime(M))
to_chat(user, "The potion only works on slimes!")
return
@@ -149,9 +149,14 @@
if(being_used)
to_chat(user, "You're already using this on another slime!")
return
-
+ if(M.rabid) //Stops being rabid, but doesn't become truly docile.
+ to_chat(M, "You absorb the potion, and your rabid hunger finally settles to a normal desire to feed.")
+ to_chat(user, "You feed the slime the potion, calming its rabid rage.")
+ M.rabid = FALSE
+ qdel(src)
+ return
M.docile = 1
- M.nutrition = 700
+ M.set_nutrition(700)
to_chat(M, "You absorb the potion and feel your intense desire to feed melt away.")
to_chat(user, "You feed the slime the potion, removing its hunger and calming it.")
being_used = 1
@@ -272,7 +277,7 @@
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle16"
-/obj/item/slimepotion/slime/steroid/attack(mob/living/carbon/slime/M, mob/user)
+/obj/item/slimepotion/slime/steroid/attack(mob/living/simple_animal/slime/M, mob/user)
if(!isslime(M))//If target is not a slime.
to_chat(user, "The steroid only works on baby slimes!")
return ..()
@@ -302,7 +307,7 @@
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle15"
-/obj/item/slimepotion/slime/stabilizer/attack(mob/living/carbon/slime/M, mob/user)
+/obj/item/slimepotion/slime/stabilizer/attack(mob/living/simple_animal/slime/M, mob/user)
if(!isslime(M))
to_chat(user, "The stabilizer only works on slimes!")
return ..()
@@ -323,7 +328,7 @@
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle3"
-/obj/item/slimepotion/slime/mutator/attack(mob/living/carbon/slime/M, mob/user)
+/obj/item/slimepotion/slime/mutator/attack(mob/living/simple_animal/slime/M, mob/user)
if(!isslime(M))
to_chat(user, "The mutator only works on slimes!")
return ..()
diff --git a/code/modules/ruins/lavalandruin_code/dead_ratvar.dm b/code/modules/ruins/lavalandruin_code/dead_ratvar.dm
index 0c57a6b6792..10beb4c0ad8 100644
--- a/code/modules/ruins/lavalandruin_code/dead_ratvar.dm
+++ b/code/modules/ruins/lavalandruin_code/dead_ratvar.dm
@@ -24,7 +24,7 @@
/obj/effect/clockwork/overlay/examine(mob/user)
if(linked)
- linked.examine(user)
+ return linked.examine(user)
/obj/effect/clockwork/overlay/ex_act()
return FALSE
diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm
index b217906b9a1..32239466b82 100644
--- a/code/modules/spacepods/spacepod.dm
+++ b/code/modules/spacepods/spacepod.dm
@@ -764,10 +764,9 @@ obj/spacepod/proc/add_equipment(mob/user, var/obj/item/spacepod_equipment/SPE, v
to_chat(user, "The nuke-disk is locking the door every time you try to open it. You get the feeling that it doesn't want to go into the spacepod.")
return 0
- for(var/mob/living/carbon/slime/S in range(1,usr))
- if(S.Victim == user)
- to_chat(user, "You're too busy getting your life sucked out of you.")
- return 0
+ if(user.has_buckled_mobs()) //mob attached to us
+ to_chat(user, "[user] will not fit into [src] because [user.p_they()] [user.p_have()] creatures attached to [user.p_them()]!")
+ return
move_inside(user)
diff --git a/code/modules/surgery/core_removal.dm b/code/modules/surgery/core_removal.dm
new file mode 100644
index 00000000000..21458720978
--- /dev/null
+++ b/code/modules/surgery/core_removal.dm
@@ -0,0 +1,61 @@
+/datum/surgery/core_removal
+ name = "core removal"
+ steps = list(/datum/surgery_step/slime/cut_flesh, /datum/surgery_step/slime/extract_core)
+ allowed_mob = list(/mob/living/simple_animal/slime)
+ possible_locs = list("chest", "head", "l_arm", "l_hand", "r_arm", "r_hand", "r_leg", "r_foot", "l_leg", "l_foot", "groin")
+
+/datum/surgery_step/slime
+
+/datum/surgery_step/slime/is_valid_target(mob/living/simple_animal/slime/target)
+ return istype(target, /mob/living/simple_animal/slime)
+
+/datum/surgery_step/slime/can_use(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool)
+ return istype(target) && target.stat == DEAD
+
+/datum/surgery_step/slime/cut_flesh
+ allowed_tools = list(/obj/item/scalpel = 100, /obj/item/melee/energy/sword = 75, /obj/item/kitchen/knife = 65, /obj/item/shard = 45)
+ time = 16
+
+/datum/surgery_step/slime/cut_flesh/begin_step(mob/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool)
+ user.visible_message("[user] starts cutting through [target]'s flesh with \the [tool].", "You start cutting through [target]'s flesh with \the [tool].")
+
+/datum/surgery_step/slime/cut_flesh/end_step(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool)
+ user.visible_message(" [user] cuts through [target]'s flesh with \the [tool].",
+ " You cut through [target]'s flesh with \the [tool], revealing its silky innards.")
+ return TRUE
+
+/datum/surgery_step/slime/cut_flesh/fail_step(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool)
+ user.visible_message(" [user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \
+ " Your hand slips, tearing [target]'s flesh with \the [tool]!")
+ return FALSE
+
+/datum/surgery_step/slime/extract_core
+ name = "extract core"
+ allowed_tools = list(/obj/item/hemostat = 100, /obj/item/crowbar = 100)
+ time = 16
+
+/datum/surgery_step/slime/extract_core/begin_step(mob/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool)
+ user.visible_message("[user] begins to extract a core from [target].",
+ "You begin to extract a core from [target]...")
+
+/datum/surgery_step/slime/extract_core/end_step(mob/user, mob/living/simple_animal/slime/slime, target_zone, obj/item/tool)
+ if(slime.cores > 0)
+ slime.cores--
+ user.visible_message("[user] successfully extracts a core from [slime]!",
+ "You successfully extract a core from [slime]. [slime.cores] core\s remaining.")
+
+ new slime.coretype(slime.loc)
+
+ if(slime.cores <= 0)
+ slime.icon_state = "[slime.colour] baby slime dead-nocore"
+ return TRUE
+ else
+ return FALSE
+ else
+ to_chat(user, "There aren't any cores left in [slime]!")
+ return TRUE
+
+/datum/surgery_step/slime/extract_core/fail_step(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool)
+ user.visible_message(" [user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \
+ " Your hand slips, tearing [target]'s flesh with \the [tool]!")
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
index 8f5700bd50d..840b2ed5749 100644
--- a/code/modules/surgery/organs/augments_arms.dm
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -30,8 +30,8 @@
transform = matrix(-1, 0, 0, 0, 1, 0)
/obj/item/organ/internal/cyberimp/arm/examine(mob/user)
- ..()
- to_chat(user, "[src] is assembled in the [parent_organ == "r_arm" ? "right" : "left"] arm configuration. You can use a screwdriver to reassemble it.")
+ . = ..()
+ . += "[src] is assembled in the [parent_organ == "r_arm" ? "right" : "left"] arm configuration. You can use a screwdriver to reassemble it."
/obj/item/organ/internal/cyberimp/arm/attackby(obj/item/I, mob/user, params)
if(isscrewdriver(I))
@@ -337,11 +337,11 @@
break
A.charging = 1
if(A.cell.charge >= 500)
- H.nutrition += 50
+ H.adjust_nutrition(50)
A.cell.charge -= 500
to_chat(H, "You siphon off some of the stored charge for your own use.")
else
- H.nutrition += A.cell.charge/10
+ H.adjust_nutrition(A.cell.charge * 0.1)
A.cell.charge = 0
to_chat(H, "You siphon off the last of \the [A]'s charge.")
break
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index 71a06d8e013..8f80b4e58e3 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -229,7 +229,7 @@
if(owner.nutrition <= hunger_threshold)
synthesizing = 1
to_chat(owner, "You feel less hungry...")
- owner.nutrition += 50
+ owner.adjust_nutrition(50)
spawn(50)
synthesizing = 0
diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm
index 29a13cf1e08..5b82fdf8c23 100644
--- a/code/modules/surgery/organs/organ.dm
+++ b/code/modules/surgery/organs/organ.dm
@@ -145,12 +145,12 @@
return 0
/obj/item/organ/examine(mob/user)
- ..(user)
+ . = ..()
if(status & ORGAN_DEAD)
if(!is_robotic())
- to_chat(user, "The decay has set in.")
+ . += "The decay has set in."
else
- to_chat(user, "It looks in need of repairs.")
+ . += "It looks in need of repairs."
/obj/item/organ/proc/handle_germ_effects()
//** Handle the effects of infections
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 4f859ea2e2b..7527ed19f92 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -285,7 +285,7 @@
/obj/item/organ/internal/honktumor/cursed/on_life() //No matter what you do, no matter who you are, no matter where you go, you're always going to be a fat, stuttering dimwit.
..()
owner.setBrainLoss(80)
- owner.nutrition = 9000
+ owner.set_nutrition(9000)
owner.overeatduration = 9000
diff --git a/code/modules/surgery/organs/subtypes/kidan.dm b/code/modules/surgery/organs/subtypes/kidan.dm
index 3778a7204cc..b87531ac337 100644
--- a/code/modules/surgery/organs/subtypes/kidan.dm
+++ b/code/modules/surgery/organs/subtypes/kidan.dm
@@ -41,7 +41,7 @@
owner.visible_message("[owner] fades to dark.")
return
- owner.nutrition = max(owner.nutrition - KIDAN_LANTERN_HUNGERCOST, KIDAN_LANTERN_HUNGERCOST)
+ owner.set_nutrition(max(owner.nutrition - KIDAN_LANTERN_HUNGERCOST, KIDAN_LANTERN_HUNGERCOST))
var/new_light = calculate_glow(KIDAN_LANTERN_LIGHT)
diff --git a/code/modules/surgery/organs/subtypes/slime.dm b/code/modules/surgery/organs/subtypes/slime.dm
new file mode 100644
index 00000000000..a1c4e5a0bf6
--- /dev/null
+++ b/code/modules/surgery/organs/subtypes/slime.dm
@@ -0,0 +1,11 @@
+/obj/item/organ/internal/heart/slime
+ icon = 'icons/obj/species_organs/slime.dmi'
+ name = "osmotic pressure regulator"
+ icon_state = "heart"
+ desc = "It appears to be some kind of biological pump that uses osmotic pressure to regulate water flow. It seems to work similar to a heart."
+
+/obj/item/organ/internal/lungs/slime
+ icon = 'icons/obj/species_organs/slime.dmi'
+ name = "gas exchange membrane"
+ icon_state = "lungs"
+ desc = "Membrane used for oxygen intake and gas exchange. These seem to work similar to lungs."
\ No newline at end of file
diff --git a/code/modules/surgery/slime.dm b/code/modules/surgery/slime.dm
deleted file mode 100644
index 77614d41430..00000000000
--- a/code/modules/surgery/slime.dm
+++ /dev/null
@@ -1,103 +0,0 @@
-//////////////////////////////////////////////////////////////////
-// SLIME CORE EXTRACTION //
-//////////////////////////////////////////////////////////////////
-/datum/surgery/core_removal
- name = "core removal"
- steps = list(/datum/surgery_step/slime/cut_flesh, /datum/surgery_step/slime/cut_innards, /datum/surgery_step/slime/saw_core)
- allowed_mob = list(/mob/living/carbon/slime)
- possible_locs = list("chest")//urgghhhhhhhhhhhh
-
-
-/datum/surgery_step/slime
- is_valid_target(mob/living/carbon/slime/target)
- return istype(target, /mob/living/carbon/slime/)
-
- can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- return target.stat == DEAD
-
-/datum/surgery_step/slime/cut_flesh
- allowed_tools = list(
- /obj/item/scalpel = 100, \
- /obj/item/kitchen/knife = 90, \
- /obj/item/shard = 60, \
- )
-
- time = 16
-
-/datum/surgery_step/slime/cut_flesh/can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- return ..() && istype(target) && target.core_removal_stage == 0
-
-/datum/surgery_step/slime/cut_flesh/begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts cutting through [target]'s flesh with \the [tool].", \
- "You start cutting through [target]'s flesh with \the [tool].")
-
-/datum/surgery_step/slime/cut_flesh/end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message(" [user] cuts through [target]'s flesh with \the [tool].", \
- " You cut through [target]'s flesh with \the [tool], revealing its silky innards.")
- target.core_removal_stage = 1
-
- return 1
-
-/datum/surgery_step/slime/cut_flesh/fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message(" [user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \
- " Your hand slips, tearing [target]'s flesh with \the [tool]!")
- return 0
-
-/datum/surgery_step/slime/cut_innards
- allowed_tools = list(
- /obj/item/scalpel = 100, \
- /obj/item/kitchen/knife = 90, \
- /obj/item/shard = 60, \
- )
-
- time = 16
-
-/datum/surgery_step/slime/cut_innards/can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- return ..() && istype(target) && target.core_removal_stage == 1
-
-/datum/surgery_step/slime/cut_innards/begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts cutting [target]'s silky innards apart with \the [tool].", \
- "You start cutting [target]'s silky innards apart with \the [tool].")
-
-/datum/surgery_step/slime/cut_innards/end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message(" [user] cuts [target]'s innards apart with \the [tool], exposing the cores.", \
- " You cut [target]'s innards apart with \the [tool], exposing the cores.")
- target.core_removal_stage = 2
- return 1
-
-/datum/surgery_step/slime/cut_innards/fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message(" [user]'s hand slips, tearing [target]'s innards with \the [tool]!", \
- " Your hand slips, tearing [target]'s innards with \the [tool]!")
- return 0
-
-/datum/surgery_step/slime/saw_core
- allowed_tools = list(
- /obj/item/circular_saw = 100, \
- /obj/item/hatchet = 90
- )
-
- time = 16
-
-/datum/surgery_step/slime/saw_core/can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- return ..() && (istype(target) && target.core_removal_stage == 2 && target.cores > 0) //This is being passed a human as target, unsure why.
-
-/datum/surgery_step/slime/saw_core/begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts cutting out one of [target]'s cores with \the [tool].", \
- "You start cutting out one of [target]'s cores with \the [tool].")
-
-/datum/surgery_step/slime/saw_core/end_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- target.cores--
- user.visible_message(" [user] cuts out one of [target]'s cores with \the [tool].", \
- " You cut out one of [target]'s cores with \the [tool]. [target.cores] cores left.")
-
- if(target.cores >= 0)
- new target.coretype(target.loc)
- if(target.cores <= 0)
- target.icon_state = "[target.colour] baby slime dead-nocore"
-
- return 1
-
-/datum/surgery_step/slime/saw_core/fail_step(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- user.visible_message(" [user]'s hand slips, causing [user.p_them()] to miss the core!", \
- " Your hand slips, causing you to miss the core!")
- return 0
diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm
index 893e9719fb4..8ff937eea6f 100644
--- a/code/modules/telesci/telepad.dm
+++ b/code/modules/telesci/telepad.dm
@@ -136,8 +136,8 @@
rcell = new(src)
/obj/item/rcs/examine(mob/user)
- ..(user)
- to_chat(user, "There are [round(rcell.charge/chargecost)] charge\s left.")
+ . = ..()
+ . += "There are [round(rcell.charge/chargecost)] charge\s left."
/obj/item/rcs/Destroy()
QDEL_NULL(rcell)
diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm
index 1deedc434a9..0f737823d5b 100644
--- a/code/modules/telesci/telesci_computer.dm
+++ b/code/modules/telesci/telesci_computer.dm
@@ -42,8 +42,8 @@
return ..()
/obj/machinery/computer/telescience/examine(mob/user)
- ..(user)
- to_chat(user, "There are [crystals ? crystals : "no"] bluespace crystal\s in the crystal slots.")
+ . = ..()
+ . += "There are [crystals ? crystals : "no"] bluespace crystal\s in the crystal slots."
/obj/machinery/computer/telescience/Initialize()
..()
diff --git a/code/modules/vehicle/ambulance.dm b/code/modules/vehicle/ambulance.dm
index f10f9d9769c..29fb4e0108f 100644
--- a/code/modules/vehicle/ambulance.dm
+++ b/code/modules/vehicle/ambulance.dm
@@ -107,7 +107,7 @@
/obj/structure/bed/amb_trolley/examine(mob/user)
. = ..()
- to_chat(user, "Drag [src]'s sprite over the ambulance to (de)attach it.")
+ . += "Drag [src]'s sprite over the ambulance to (de)attach it."
/obj/structure/bed/amb_trolley/MouseDrop(obj/over_object as obj)
..()
diff --git a/code/modules/vehicle/janicart.dm b/code/modules/vehicle/janicart.dm
index 0f4382c92d1..2445e983fd3 100644
--- a/code/modules/vehicle/janicart.dm
+++ b/code/modules/vehicle/janicart.dm
@@ -56,9 +56,9 @@
/obj/vehicle/janicart/examine(mob/user)
- ..()
+ . = ..()
if(floorbuffer)
- to_chat(user, "It has been upgraded with a floor buffer.")
+ . += "It has been upgraded with a floor buffer."
/obj/vehicle/janicart/attackby(obj/item/I, mob/user, params)
diff --git a/html/changelog.html b/html/changelog.html
index c9a4359caf0..d40cde16a74 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -56,6 +56,111 @@
-->
+
26 September 2019
+
AzuleUtama updated:
+
+ - Improvised shotguns are now in the correct tab when trying to craft them.
+
+
Couls updated:
+
+ - Slime lungs and heart
+ - Slimes no longer take toxins damage from blood loss
+ - Slimes no longer take brute damage in crit
+ - Slimes now breathe
+ - slimes now use new crit
+
+
Kyep updated:
+
+ - Fixed NPC redsuited syndicates from being unable to move in space.
+ - Fixed NPC bots thinking that they can path through airlocks which are welded shut. refactor: Refactors some safety checks so that its impossible for depot mobs to generate runtimes in rare cases (e.g: admins spawning them outside the depot for testing)
+
+
MrMagolor updated:
+
+ - Cult pylons no longer delete unsimulated walls and turn them into floors.
+ - Cult pylons now turn simulated walls into cult walls.
+
+
TDSSS updated:
+
+ - added missing tools to one abductor ship
+
+
farie82 updated:
+
+ - Morphs examine text now stays true to the humanoid target they choose.
+ - Cult constructs now show their examine text when you're next to it. Instead of on top of it.
+
+
+
24 September 2019
+
AzuleUtama updated:
+
+ - Fixed misleading uplink description for chef's traitor knife.
+ - Reorganises products in seed vendor.
+ - Fixes Durathread mutating into more Durathread
+
+
Dave-TH updated:
+
+ - Mob spawners will no longer sometimes send players to the void.
+ - The ghosts inside possessed blades are now invincible and will not die to weird edge cases.
+
+
Evankhell561 updated:
+
+ - mechs now start with a high-capacity power cell+
+
+
Fox McCloud updated:
+
+ - Buckling has its own icon
+ - Fixes Xenobio monkey shortcuts not working
+ - Bodyscanners are similar to sleepers; interact with them by clicking on the scanner; there is no console anymore
+ - Summon guns/magic is no longer free, but costs 2 spells points
+ - Summon guns/magic makes 10% of the crew antags with the objective to collect guns/magical items and kill anyone who gets in their way
+ - If a wizard (or admin) summons guns/magic, latejoiners to the round will also acquire summoned items
+ - Wizard's hardsuit is now battlemage armor
+ - Battlemage armor protects you from pressure of space (but not the cold), has no slowdown, and a moderate amount of armor, however, it has 16 shields to block incoming attacks
+ - Can purchase additional charges for your battlemage armor for 1 spell point
+ - Shielded hardsuits now show the shield on the mob
+ - Abductors, Skeletons, Shadowlings, and Plasmamen never get hungry
+ - Abductors, Skeleton, and Plasmamen can't taste anything
+ - Wood Golems now have a diet and taste sensitivity much like Diona
+ - Unathi are more sensitive to tastes
+ - Adjusted the sensitivity of "sharp" and "dull" tastes a bit
+ - Slimes are a simple mob subtype
+ - using a bloodlust slime potion on a docile slime removes the docility
+ - using a docility potion on a rabid slime calms them down
+ - slime core removal surgery steps are now just scalpel->hemostat
+ - Slimes have action buttons to feed on, evolve, or reproduce
+ - Fixes beepsky arresting slimes (maybe it should be a feature....)
+ - Fixes Seed Vault gene modder having limitations
+ - Fixes not being able to extinguish some items
+
+
Ionward updated:
+
+ - Fixed Tajaran fat sprites, they are no longer duplicates of their slim torso.
+ - Fixed fat aqua jumpsuit only using one direction.
+ - Fixed missing Lasagna icon.
+
+
Kyep updated:
+
+ - The Hierophant club and warp cubes (lavaland loot) no longer allow you to teleport into or out of areas that are set to forbid teleports.
+ - Fixed a small bug that caused coins named "syndicate coin" or "antag token" to both incorrectly appear as "valid coin".
+
+
Markolie updated:
+
+ - Fixed naked equipment selection and reincarnation not working.
+
+
TDSSS updated:
+
+ - all huds are the first option when ghosts cycle through huds
+ - fixed brig door timers from announcing admin names when stopped via admin powers.
+
+
Ty-Omaha updated:
+
+ - You can now silence the current midi with a verb in the preferences tab, without affecting your prefrence to hear midis in the future.
+
+
datlo updated:
+
+ - Fixed clown changelings not losing comic sans on transformation
+ - Clowns can now lose the clumsy and comic genes through DNA manipulation (but not mutadone)
+
+
22 September 2019
Evankhell561 updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 1207e01fa7a..cbc77462782 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -11495,3 +11495,91 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
does not cause a runtime anymore
TDSSS:
- tweak: Just slight gloves refactor, shouldn't impact anything in game.
+2019-09-24:
+ AzuleUtama:
+ - bugfix: Fixed misleading uplink description for chef's traitor knife.
+ - tweak: Reorganises products in seed vendor.
+ - bugfix: Fixes Durathread mutating into more Durathread
+ Dave-TH:
+ - bugfix: Mob spawners will no longer sometimes send players to the void.
+ - bugfix: The ghosts inside possessed blades are now invincible and will not die
+ to weird edge cases.
+ Evankhell561:
+ - tweak: mechs now start with a high-capacity power cell+
+ Fox McCloud:
+ - tweak: Buckling has its own icon
+ - bugfix: Fixes Xenobio monkey shortcuts not working
+ - tweak: Bodyscanners are similar to sleepers; interact with them by clicking on
+ the scanner; there is no console anymore
+ - rscadd: Summon guns/magic is no longer free, but costs 2 spells points
+ - rscadd: Summon guns/magic makes 10% of the crew antags with the objective to collect
+ guns/magical items and kill anyone who gets in their way
+ - rscadd: If a wizard (or admin) summons guns/magic, latejoiners to the round will
+ also acquire summoned items
+ - tweak: Wizard's hardsuit is now battlemage armor
+ - tweak: Battlemage armor protects you from pressure of space (but not the cold),
+ has no slowdown, and a moderate amount of armor, however, it has 16 shields
+ to block incoming attacks
+ - rscadd: Can purchase additional charges for your battlemage armor for 1 spell
+ point
+ - tweak: Shielded hardsuits now show the shield on the mob
+ - rscadd: Abductors, Skeletons, Shadowlings, and Plasmamen never get hungry
+ - tweak: Abductors, Skeleton, and Plasmamen can't taste anything
+ - tweak: Wood Golems now have a diet and taste sensitivity much like Diona
+ - tweak: Unathi are more sensitive to tastes
+ - tweak: Adjusted the sensitivity of "sharp" and "dull" tastes a bit
+ - tweak: Slimes are a simple mob subtype
+ - rscadd: using a bloodlust slime potion on a docile slime removes the docility
+ - rscadd: using a docility potion on a rabid slime calms them down
+ - tweak: slime core removal surgery steps are now just scalpel->hemostat
+ - rscadd: Slimes have action buttons to feed on, evolve, or reproduce
+ - bugfix: Fixes beepsky arresting slimes (maybe it should be a feature....)
+ - bugfix: Fixes Seed Vault gene modder having limitations
+ - bugfix: Fixes not being able to extinguish some items
+ Ionward:
+ - bugfix: Fixed Tajaran fat sprites, they are no longer duplicates of their slim
+ torso.
+ - bugfix: Fixed fat aqua jumpsuit only using one direction.
+ - bugfix: Fixed missing Lasagna icon.
+ Kyep:
+ - bugfix: The Hierophant club and warp cubes (lavaland loot) no longer allow you
+ to teleport into or out of areas that are set to forbid teleports.
+ - bugfix: Fixed a small bug that caused coins named "syndicate coin" or "antag token"
+ to both incorrectly appear as "valid coin".
+ Markolie:
+ - bugfix: Fixed naked equipment selection and reincarnation not working.
+ TDSSS:
+ - tweak: all huds are the first option when ghosts cycle through huds
+ - bugfix: fixed brig door timers from announcing admin names when stopped via admin
+ powers.
+ Ty-Omaha:
+ - rscadd: You can now silence the current midi with a verb in the preferences tab,
+ without affecting your prefrence to hear midis in the future.
+ datlo:
+ - bugfix: Fixed clown changelings not losing comic sans on transformation
+ - tweak: Clowns can now lose the clumsy and comic genes through DNA manipulation
+ (but not mutadone)
+2019-09-26:
+ AzuleUtama:
+ - bugfix: Improvised shotguns are now in the correct tab when trying to craft them.
+ Couls:
+ - rscadd: Slime lungs and heart
+ - rscdel: Slimes no longer take toxins damage from blood loss
+ - rscdel: Slimes no longer take brute damage in crit
+ - rscadd: Slimes now breathe
+ - tweak: slimes now use new crit
+ Kyep:
+ - bugfix: Fixed NPC redsuited syndicates from being unable to move in space.
+ - bugfix: 'Fixed NPC bots thinking that they can path through airlocks which are
+ welded shut. refactor: Refactors some safety checks so that its impossible for
+ depot mobs to generate runtimes in rare cases (e.g: admins spawning them outside
+ the depot for testing)'
+ MrMagolor:
+ - bugfix: Cult pylons no longer delete unsimulated walls and turn them into floors.
+ - tweak: Cult pylons now turn simulated walls into cult walls.
+ TDSSS:
+ - bugfix: added missing tools to one abductor ship
+ farie82:
+ - bugfix: Morphs examine text now stays true to the humanoid target they choose.
+ - tweak: Cult constructs now show their examine text when you're next to it. Instead
+ of on top of it.
diff --git a/html/changelogs/AutoChangeLog-pr-12372.yml b/html/changelogs/AutoChangeLog-pr-12372.yml
deleted file mode 100644
index e294bb4c03e..00000000000
--- a/html/changelogs/AutoChangeLog-pr-12372.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "datlo"
-delete-after: True
-changes:
- - bugfix: "Fixed clown changelings not losing comic sans on transformation"
- - tweak: "Clowns can now lose the clumsy and comic genes through DNA manipulation (but not mutadone)"
diff --git a/html/changelogs/AutoChangeLog-pr-12373.yml b/html/changelogs/AutoChangeLog-pr-12373.yml
deleted file mode 100644
index c6104a19c10..00000000000
--- a/html/changelogs/AutoChangeLog-pr-12373.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "TDSSS"
-delete-after: True
-changes:
- - tweak: "all huds are the first option when ghosts cycle through huds"
diff --git a/html/changelogs/AutoChangeLog-pr-12375.yml b/html/changelogs/AutoChangeLog-pr-12375.yml
deleted file mode 100644
index 4391987e967..00000000000
--- a/html/changelogs/AutoChangeLog-pr-12375.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Fox McCloud"
-delete-after: True
-changes:
- - tweak: "Buckling has its own icon"
- - bugfix: "Fixes Xenobio monkey shortcuts not working"
diff --git a/html/changelogs/AutoChangeLog-pr-12377.yml b/html/changelogs/AutoChangeLog-pr-12377.yml
deleted file mode 100644
index 529267617e0..00000000000
--- a/html/changelogs/AutoChangeLog-pr-12377.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fox McCloud"
-delete-after: True
-changes:
- - tweak: "Bodyscanners are similar to sleepers; interact with them by clicking on the scanner; there is no console anymore"
diff --git a/html/changelogs/AutoChangeLog-pr-12380.yml b/html/changelogs/AutoChangeLog-pr-12380.yml
deleted file mode 100644
index 89a5fe22f1d..00000000000
--- a/html/changelogs/AutoChangeLog-pr-12380.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "TDSSS"
-delete-after: True
-changes:
- - bugfix: "fixed brig door timers from announcing admin names when stopped via admin powers."
diff --git a/html/changelogs/AutoChangeLog-pr-12387.yml b/html/changelogs/AutoChangeLog-pr-12387.yml
deleted file mode 100644
index 60df714e6b0..00000000000
--- a/html/changelogs/AutoChangeLog-pr-12387.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Markolie"
-delete-after: True
-changes:
- - bugfix: "Fixed naked equipment selection and reincarnation not working."
diff --git a/html/changelogs/AutoChangeLog-pr-12431.yml b/html/changelogs/AutoChangeLog-pr-12431.yml
new file mode 100644
index 00000000000..af6524de08a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12431.yml
@@ -0,0 +1,4 @@
+author: "PidgeyThePirate"
+delete-after: True
+changes:
+ - bugfix: "Rebooting a drone no longer requires both engineering and robotics access."
diff --git a/html/changelogs/AutoChangeLog-pr-12432.yml b/html/changelogs/AutoChangeLog-pr-12432.yml
new file mode 100644
index 00000000000..ac1ff133849
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12432.yml
@@ -0,0 +1,4 @@
+author: "PidgeyThePirate"
+delete-after: True
+changes:
+ - bugfix: "fixed a rare glitch in which a guardian that is killed instantly (i.e by a wand of death) may draw its charge into null space."
diff --git a/html/changelogs/AutoChangeLog-pr-12433.yml b/html/changelogs/AutoChangeLog-pr-12433.yml
new file mode 100644
index 00000000000..ae53494a9a0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12433.yml
@@ -0,0 +1,4 @@
+author: "PidgeyThePirate"
+delete-after: True
+changes:
+ - tweak: "bluespace anomalies no longer teleport ghosts when their event fires."
diff --git a/html/changelogs/AutoChangeLog-pr-12435.yml b/html/changelogs/AutoChangeLog-pr-12435.yml
new file mode 100644
index 00000000000..a7b6cfbe085
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-12435.yml
@@ -0,0 +1,4 @@
+author: "SteelSlayer"
+delete-after: True
+changes:
+ - bugfix: "Fixes round-start autotraitors not getting their objectives and uplink codes"
diff --git a/icons/mob/actions/actions_slime.dmi b/icons/mob/actions/actions_slime.dmi
new file mode 100644
index 00000000000..acf7a31c6ed
Binary files /dev/null and b/icons/mob/actions/actions_slime.dmi differ
diff --git a/icons/mob/human_races/r_tajaran.dmi b/icons/mob/human_races/r_tajaran.dmi
index 3f45032951d..d15b5fc9544 100644
Binary files a/icons/mob/human_races/r_tajaran.dmi and b/icons/mob/human_races/r_tajaran.dmi differ
diff --git a/icons/mob/slimes.dmi b/icons/mob/slimes.dmi
index 0ef5ac0bee4..f9998d6f106 100644
Binary files a/icons/mob/slimes.dmi and b/icons/mob/slimes.dmi differ
diff --git a/icons/mob/uniform_fat.dmi b/icons/mob/uniform_fat.dmi
index 29327ef5413..31fdc67edae 100644
Binary files a/icons/mob/uniform_fat.dmi and b/icons/mob/uniform_fat.dmi differ
diff --git a/icons/obj/species_organs/slime.dmi b/icons/obj/species_organs/slime.dmi
new file mode 100644
index 00000000000..58ec636ca7e
Binary files /dev/null and b/icons/obj/species_organs/slime.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 08cfe4087f2..a9ad9f7a46a 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1238,6 +1238,9 @@
#include "code\modules\antagonists\_common\antag_hud.dm"
#include "code\modules\antagonists\_common\antag_spawner.dm"
#include "code\modules\antagonists\_common\antag_team.dm"
+#include "code\modules\antagonists\survivalist\survivalist.dm"
+#include "code\modules\antagonists\traitor\datum_mindslave.dm"
+#include "code\modules\antagonists\traitor\datum_traitor.dm"
#include "code\modules\antagonists\wishgranter\wishgranter.dm"
#include "code\modules\arcade\arcade_base.dm"
#include "code\modules\arcade\arcade_prize.dm"
@@ -1835,15 +1838,6 @@
#include "code\modules\mob\living\carbon\human\species\vulpkanin.dm"
#include "code\modules\mob\living\carbon\human\species\wryn.dm"
#include "code\modules\mob\living\carbon\human\species\zombies.dm"
-#include "code\modules\mob\living\carbon\slime\death.dm"
-#include "code\modules\mob\living\carbon\slime\emote.dm"
-#include "code\modules\mob\living\carbon\slime\examine.dm"
-#include "code\modules\mob\living\carbon\slime\life.dm"
-#include "code\modules\mob\living\carbon\slime\powers.dm"
-#include "code\modules\mob\living\carbon\slime\say.dm"
-#include "code\modules\mob\living\carbon\slime\slime.dm"
-#include "code\modules\mob\living\carbon\slime\subtypes.dm"
-#include "code\modules\mob\living\carbon\slime\update_icons.dm"
#include "code\modules\mob\living\silicon\death.dm"
#include "code\modules\mob\living\silicon\emote.dm"
#include "code\modules\mob\living\silicon\laws.dm"
@@ -1941,7 +1935,6 @@
#include "code\modules\mob\living\simple_animal\friendly\mouse.dm"
#include "code\modules\mob\living\simple_animal\friendly\penguin.dm"
#include "code\modules\mob\living\simple_animal\friendly\pet.dm"
-#include "code\modules\mob\living\simple_animal\friendly\slime.dm"
#include "code\modules\mob\living\simple_animal\friendly\sloth.dm"
#include "code\modules\mob\living\simple_animal\friendly\spiderbot.dm"
#include "code\modules\mob\living\simple_animal\hostile\alien.dm"
@@ -2016,6 +2009,13 @@
#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\terror_ai.dm"
#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\terror_spiders.dm"
#include "code\modules\mob\living\simple_animal\hostile\terror_spiders\white.dm"
+#include "code\modules\mob\living\simple_animal\slime\death.dm"
+#include "code\modules\mob\living\simple_animal\slime\emote.dm"
+#include "code\modules\mob\living\simple_animal\slime\life.dm"
+#include "code\modules\mob\living\simple_animal\slime\powers.dm"
+#include "code\modules\mob\living\simple_animal\slime\say.dm"
+#include "code\modules\mob\living\simple_animal\slime\slime.dm"
+#include "code\modules\mob\living\simple_animal\slime\subtypes.dm"
#include "code\modules\mob\new_player\login.dm"
#include "code\modules\mob\new_player\logout.dm"
#include "code\modules\mob\new_player\new_player.dm"
@@ -2395,6 +2395,7 @@
#include "code\modules\store\store.dm"
#include "code\modules\surgery\bones.dm"
#include "code\modules\surgery\cavity_implant.dm"
+#include "code\modules\surgery\core_removal.dm"
#include "code\modules\surgery\dental_implant.dm"
#include "code\modules\surgery\encased.dm"
#include "code\modules\surgery\generic.dm"
@@ -2408,7 +2409,6 @@
#include "code\modules\surgery\remove_embedded_object.dm"
#include "code\modules\surgery\rig_removal.dm"
#include "code\modules\surgery\robotics.dm"
-#include "code\modules\surgery\slime.dm"
#include "code\modules\surgery\surgery.dm"
#include "code\modules\surgery\tools.dm"
#include "code\modules\surgery\organs\augments_arms.dm"
@@ -2444,6 +2444,7 @@
#include "code\modules\surgery\organs\subtypes\plasmaman.dm"
#include "code\modules\surgery\organs\subtypes\shadow.dm"
#include "code\modules\surgery\organs\subtypes\skrell.dm"
+#include "code\modules\surgery\organs\subtypes\slime.dm"
#include "code\modules\surgery\organs\subtypes\standard.dm"
#include "code\modules\surgery\organs\subtypes\tajaran.dm"
#include "code\modules\surgery\organs\subtypes\unathi.dm"