diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 2f58d4e9ebb..a8a0459bcb1 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -7,4 +7,4 @@ assignees: ''
---
-Please place all features requests here: https://nanotrasen.se/forum/60-suggestions/
+Please place all features requests here: https://www.paradisestation.org/forum/60-suggestions/
diff --git a/README.md b/README.md
index d60fe8006c8..eafdb5ffe91 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
[](http://forthebadge.com)
[](http://forthebadge.com)
-[Website](https://nanotrasen.se/) - [Code](https://github.com/ParadiseSS13/Paradise) - [Discord](https://discordapp.com/invite/YJDsXFE)
+[Website](https://www.paradisestation.org/) - [Code](https://github.com/ParadiseSS13/Paradise) - [Discord](https://discordapp.com/invite/YJDsXFE)
---
@@ -104,7 +104,7 @@ Your server details go in /config/dbconfig.txt,
and the SQL schema is in /SQL/paradise_schema.sql or /SQL/paradise_schema_prefix.sql,
depending on if you want table prefixes.
More detailed setup instructions are located on our wiki:
-https://nanotrasen.se/wiki/index.php/Setting_up_the_Database
+https://www.paradisestation.org/wiki/index.php/Setting_up_the_Database
---
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index df957eaa11e..f9fba3ff4a4 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -155,6 +155,7 @@
// /mob/living/carbon signals
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
+#define COMSIG_CARBON_LIFE "carbon_life" //from base of mob/living/carbon/Life() ()
// /mob/living/simple_animal/hostile signals
#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 7dd5fc5a609..169a5129eee 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -384,7 +384,7 @@
#define EXPLOSIVE_WALL_GROUP_SYNDICATE_BASE "syndicate_base"
// Filters
-#define FILTER_AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, border=4, color="#04080FAA")
+#define FILTER_AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, color="#04080FAA")
//Fullscreen overlay resolution in tiles.
#define FULLSCREEN_OVERLAY_RESOLUTION_X 15
diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm
index 49983658d48..5ffe891d95b 100644
--- a/code/__HELPERS/lists.dm
+++ b/code/__HELPERS/lists.dm
@@ -69,11 +69,6 @@
return list[index]
return
-/proc/islist(list/list)
- if(istype(list))
- return 1
- return 0
-
//Return either pick(list) or null if list is not of type /list or is empty
/proc/safepick(list/list)
if(!islist(list) || !list.len)
diff --git a/code/__HELPERS/traits.dm b/code/__HELPERS/traits.dm
index 472caea4490..7c1d2257e27 100644
--- a/code/__HELPERS/traits.dm
+++ b/code/__HELPERS/traits.dm
@@ -62,6 +62,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
//mob traits
#define TRAIT_PACIFISM "pacifism"
+#define TRAIT_WATERBREATH "waterbreathing"
// common trait sources
#define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention
\ No newline at end of file
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 82295bc9d80..f1611b38fd9 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -540,9 +540,20 @@ Returns 1 if the chain up to the area contains the given typepath
/proc/between(var/low, var/middle, var/high)
return max(min(middle, high), low)
-proc/arctan(x)
+
+
+#if DM_VERSION > 513
+#warn 513 is definitely stable now, remove this
+#endif
+#if DM_VERSION < 513
+/proc/arctan(x)
var/y=arcsin(x/sqrt(1+x*x))
return y
+/proc/islist(list/list)
+ if(istype(list))
+ return 1
+ return 0
+#endif
//returns random gauss number
proc/GaussRand(var/sigma)
diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm
index a5586578b3f..9c0f498cd83 100644
--- a/code/_onclick/hud/plane_master.dm
+++ b/code/_onclick/hud/plane_master.dm
@@ -16,7 +16,7 @@
filters += filter(type = "outline", size = _size, color = _color)
/obj/screen/plane_master/proc/shadow(_size, _border, _offset = 0, _x = 0, _y = 0, _color = "#04080FAA")
- filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset, border = _border)
+ filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset)
/obj/screen/plane_master/proc/clear_filters()
filters = list()
diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm
index 166083b36ff..504a2d74a2c 100644
--- a/code/controllers/subsystem/jobs.dm
+++ b/code/controllers/subsystem/jobs.dm
@@ -421,23 +421,23 @@ SUBSYSTEM_DEF(jobs)
to_chat(H, "You are the [alt_title ? alt_title : rank].")
to_chat(H, "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.")
- to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)")
+ to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)")
if(job.is_service)
- to_chat(H, "As a member of Service, make sure to read up on your Department SOP")
+ to_chat(H, "As a member of Service, make sure to read up on your Department SOP")
if(job.is_supply)
- to_chat(H, "As a member of Supply, make sure to read up on your Department SOP")
+ to_chat(H, "As a member of Supply, make sure to read up on your Department SOP")
if(job.is_command)
- to_chat(H, "As an important member of Command, read up on your Department SOP")
+ to_chat(H, "As an important member of Command, read up on your Department SOP")
if(job.is_legal)
- to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure")
+ to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure")
if(job.is_engineering)
- to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP")
+ to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP")
if(job.is_medical)
- to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP")
+ to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP")
if(job.is_science)
- to_chat(H, "As a member of Science, make sure to read up on your Department SOP")
+ to_chat(H, "As a member of Science, make sure to read up on your Department SOP")
if(job.is_security)
- to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP")
+ to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP")
if(job.req_admin_notify)
to_chat(H, "You are playing a job that is important for the game progression. If you have to disconnect, please notify the admins via adminhelp.")
diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm
index 2f07f106d2a..4aa7eafbed6 100644
--- a/code/datums/spells/area_teleport.dm
+++ b/code/datums/spells/area_teleport.dm
@@ -25,10 +25,13 @@
var/A = null
if(!randomise_selection)
- A = input("Area to teleport to", "Teleport", A) in teleportlocs
+ A = input("Area to teleport to", "Teleport", A) as null|anything in teleportlocs
else
A = pick(teleportlocs)
+ if(!A)
+ return
+
var/area/thearea = teleportlocs[A]
if(thearea.tele_proof && !istype(thearea, /area/wizard_station))
diff --git a/code/datums/spells/cluwne.dm b/code/datums/spells/cluwne.dm
index 6a87419886c..58a33e31a44 100644
--- a/code/datums/spells/cluwne.dm
+++ b/code/datums/spells/cluwne.dm
@@ -17,7 +17,7 @@
var/obj/item/organ/internal/brain/cluwne/idiot_brain = new
idiot_brain.insert(src, make_cluwne = 0)
idiot_brain.dna = dna.Clone()
- setBrainLoss(80)
+ setBrainLoss(80, use_brain_mod = FALSE)
set_nutrition(9000)
overeatduration = 9000
Confused(30)
diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm
index b6a0213f82f..a9d1c3bb480 100644
--- a/code/game/gamemodes/changeling/evolution_menu.dm
+++ b/code/game/gamemodes/changeling/evolution_menu.dm
@@ -383,6 +383,9 @@ var/list/sting_paths
var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste
mind.changeling.absorbed_dna |= C.dna.Clone()
mind.changeling.trim_dna()
+
+ RegisterSignal(C, COMSIG_CARBON_LIFE, CALLBACK(C, /mob/living/carbon/.proc/handle_changeling))
+
return 1
//Used to dump the languages from the changeling datum into the actual mob.
@@ -421,6 +424,8 @@ var/list/sting_paths
if(hud_used)
hud_used.lingstingdisplay.icon_state = null
hud_used.lingstingdisplay.invisibility = 101
+ hud_used.lingchemdisplay.invisibility = 101
+ UnregisterSignal(src, COMSIG_CARBON_LIFE)
/datum/changeling/proc/has_sting(datum/action/power)
for(var/datum/action/P in purchasedpowers)
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index d30ac4f8a68..3489a087ec0 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -198,7 +198,7 @@ var/list/blacklisted_pylon_turfs = typecacheof(list(
if(last_heal <= world.time)
last_heal = world.time + heal_delay
for(var/mob/living/L in range(5, src))
- if(iscultist(L) || istype(L, /mob/living/simple_animal/shade) || istype(L, /mob/living/simple_animal/hostile/construct))
+ if(iscultist(L) || iswizard(L) || istype(L, /mob/living/simple_animal/shade) || istype(L, /mob/living/simple_animal/hostile/construct))
if(L.health != L.maxHealth)
new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
if(ishuman(L))
diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm
index 908eaa5360f..9fce3cc6e24 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction.dm
@@ -184,7 +184,7 @@
var/obj/machinery/abductor/console/con = get_team_console(team_number)
var/datum/objective/objective = team_objectives[team_number]
if(con.experiment.points >= objective.target_amount)
- SSshuttle.emergency.request(null, 0.5)
+ SSshuttle.emergency.request(null, 0.5, reason = "Large amount of abnormal thought patterns detected. All crew are recalled for mandatory evaluation and reconditioning.")
SSshuttle.emergency.canRecall = FALSE
finished = 1
return ..()
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index b761af6db92..f86f018757e 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -162,7 +162,7 @@
to_chat(src, "You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.")
to_chat(src, "To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.")
to_chat(src, "You do not remember anything of your past lives, nor will you remember anything about this one after your death.")
- to_chat(src, "Be sure to read the wiki page at http://nanotrasen.se/wiki/index.php/Revenant to learn more.")
+ to_chat(src, "Be sure to read the wiki page at http://www.paradisestation.org/wiki/index.php/Revenant to learn more.")
var/datum/objective/revenant/objective = new
objective.owner = mind
mind.objectives += objective
diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm
index b580f88c0b7..b4b4b265711 100644
--- a/code/game/gamemodes/shadowling/shadowling.dm
+++ b/code/game/gamemodes/shadowling/shadowling.dm
@@ -126,7 +126,7 @@ Made by Xhuis
to_chat(shadow.current, "Currently, you are disguised as an employee aboard [world.name].")
to_chat(shadow.current, "In your limited state, you have two abilities: Hatch and Shadowling Hivemind (:8).")
to_chat(shadow.current, "Any other shadowlings are your allies. You must assist them as they shall assist you.")
- to_chat(shadow.current, "If you are new to shadowling, or want to read about abilities, check the wiki page at http://nanotrasen.se/wiki/index.php/Shadowling
")
+ to_chat(shadow.current, "If you are new to shadowling, or want to read about abilities, check the wiki page at https://www.paradisestation.org/wiki/index.php/Shadowling
")
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index 520e6939b60..2edbb41cb95 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -205,19 +205,19 @@
/obj/item/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob)
switch(choice)
if("FORCE")
- var/obj/item/soulstone/C = src
+ var/obj/item/soulstone/SS = src
var/mob/living/T = target
if(T.client != null)
- C.init_shade(T, U)
+ SS.init_shade(T, U)
else
to_chat(U, "Capture failed!: The soul has already fled its mortal frame. You attempt to bring it back...")
T.Paralyse(20)
- if(!C.getCultGhost(T,U))
+ if(!SS.getCultGhost(T,U))
T.dust() //If we can't get a ghost, kill the sacrifice anyway.
if("VICTIM")
var/mob/living/carbon/human/T = target
- var/obj/item/soulstone/C = src
+ var/obj/item/soulstone/SS = src
if(T.stat == 0)
to_chat(U, "Capture failed!: Kill or maim the victim first!")
else
@@ -226,92 +226,67 @@
else
if(T.client == null)
to_chat(U, "Capture failed!: The soul has already fled its mortal frame. You attempt to bring it back...")
- C.getCultGhost(T,U)
+ SS.getCultGhost(T,U)
else
- if(C.contents.len)
+ if(SS.contents.len)
to_chat(U, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.")
else
- C.init_shade(T, U, vic = 1)
+ SS.init_shade(T, U, vic = 1)
if("SHADE")
var/mob/living/simple_animal/shade/T = target
- var/obj/item/soulstone/C = src
- if(!C.can_use(U))
+ var/obj/item/soulstone/SS = src
+ if(!SS.can_use(U))
U.Paralyse(5)
to_chat(U, "Your body is wracked with debilitating pain!")
return
if(T.stat == DEAD)
to_chat(U, "Capture failed!: The shade has already been banished!")
else
- if(C.contents.len)
+ if(SS.contents.len)
to_chat(U, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.")
else
- T.loc = C //put shade in stone
+ T.loc = SS //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
T.health = T.maxHealth
T.faction |= "\ref[U]"
- C.icon_state = "soulstone2"
+ SS.icon_state = "soulstone2"
to_chat(T, "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form")
to_chat(U, "Capture successful!: [T.name]'s has been recaptured and stored within the soul stone.")
if("CONSTRUCT")
var/obj/structure/constructshell/T = target
- var/obj/item/soulstone/C = src
- var/mob/living/simple_animal/shade/A = locate() in C
- if(A)
+ var/obj/item/soulstone/SS = src
+ var/mob/living/simple_animal/shade/SH = locate() in SS
+ if(SH)
var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
switch(construct_class)
if("Juggernaut")
- var/mob/living/simple_animal/hostile/construct/armoured/Z = new /mob/living/simple_animal/hostile/construct/armoured (get_turf(T.loc))
- Z.key = A.key
- Z.faction |= "\ref[U]"
- if(iscultist(U))
- if(SSticker.mode.name == "cult")
- SSticker.mode:add_cultist(Z.mind)
- else
- SSticker.mode.cult+=Z.mind
- SSticker.mode.update_cult_icons_added(Z.mind)
- qdel(T)
- to_chat(Z, "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.")
- to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.")
- Z.cancel_camera()
- qdel(C)
+ var/mob/living/simple_animal/hostile/construct/armoured/C = new /mob/living/simple_animal/hostile/construct/armoured (get_turf(T.loc))
+ to_chat(C, "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.")
+ init_construct(C,SH,SS,T)
if("Wraith")
- var/mob/living/simple_animal/hostile/construct/wraith/Z = new /mob/living/simple_animal/hostile/construct/wraith (get_turf(T.loc))
- Z.key = A.key
- Z.faction |= "\ref[U]"
- if(iscultist(U))
- if(SSticker.mode.name == "cult")
- SSticker.mode:add_cultist(Z.mind)
- else
- SSticker.mode.cult+=Z.mind
- SSticker.mode.update_cult_icons_added(Z.mind)
- qdel(T)
- to_chat(Z, "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.")
- to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.")
- Z.cancel_camera()
- qdel(C)
+ var/mob/living/simple_animal/hostile/construct/wraith/C = new /mob/living/simple_animal/hostile/construct/wraith (get_turf(T.loc))
+ to_chat(C, "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.")
+ init_construct(C,SH,SS,T)
if("Artificer")
- var/mob/living/simple_animal/hostile/construct/builder/Z = new /mob/living/simple_animal/hostile/construct/builder (get_turf(T.loc))
- Z.key = A.key
- Z.faction |= "\ref[U]"
- if(iscultist(U))
- if(SSticker.mode.name == "cult")
- SSticker.mode:add_cultist(Z.mind)
- else
- SSticker.mode.cult+=Z.mind
- SSticker.mode.update_cult_icons_added(Z.mind)
- qdel(T)
- to_chat(Z, "You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), and most important of all create new constructs (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).")
- to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.")
- Z.cancel_camera()
- qdel(C)
+ var/mob/living/simple_animal/hostile/construct/builder/C = new /mob/living/simple_animal/hostile/construct/builder (get_turf(T.loc))
+ to_chat(C, "You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), and most important of all create new constructs (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).")
+ init_construct(C,SH,SS,T)
else
to_chat(U, "Creation failed!: The soul stone is empty! Go kill someone!")
return
+/proc/init_construct(mob/living/simple_animal/hostile/construct/C, mob/living/simple_animal/shade/SH, obj/item/soulstone/SS, obj/structure/constructshell/T)
+ SH.mind.transfer_to(C)
+ qdel(T)
+ qdel(SH)
+ to_chat(C, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.")
+ C.cancel_camera()
+ qdel(SS)
+
/proc/makeNewConstruct(var/mob/living/simple_animal/hostile/construct/ctype, var/mob/target, var/mob/stoner = null, cultoverride = 0)
if(jobban_isbanned(target, "cultist") || jobban_isbanned(target, "Syndicate"))
return
@@ -325,11 +300,11 @@
SSticker.mode.cult+=newstruct.mind
SSticker.mode.update_cult_icons_added(newstruct.mind)
if(stoner && iswizard(stoner))
- to_chat(newstruct, "You are still bound to serve your creator, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.")
+ to_chat(newstruct, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.")
else if(stoner && iscultist(stoner))
- to_chat(newstruct, "You are still bound to serve the cult, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.")
+ to_chat(newstruct, "You are still bound to serve the cult, follow their orders and help them complete their goals at all costs.")
else
- to_chat(newstruct, "You are still bound to serve your creator, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.")
+ to_chat(newstruct, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.")
newstruct.cancel_camera()
/obj/item/soulstone/proc/init_shade(mob/living/T, mob/U, vic = 0)
@@ -348,17 +323,22 @@
S.name = "Shade of [T.real_name]"
S.real_name = "Shade of [T.real_name]"
S.key = T.key
- if(U)
- S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation
- if(U && iscultist(U))
- SSticker.mode.add_cultist(S.mind, 0)
S.cancel_camera()
name = "soulstone: Shade of [T.real_name]"
icon_state = "soulstone2"
- if(U && iswizard(U))
- to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help [U.p_them()] succeed in their goals at all costs.")
- else if(U && iscultist(U))
- to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help [U.p_them()] succeed in their goals at all costs.")
+ if(U)
+ S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation
+ if(iswizard(U))
+ SSticker.mode.update_wiz_icons_added(S.mind)
+ S.mind.special_role = SPECIAL_ROLE_WIZARD_APPRENTICE
+ if(iscultist(U))
+ SSticker.mode.add_cultist(S.mind, 0)
+ S.mind.special_role = SPECIAL_ROLE_CULTIST
+ S.mind.store_memory("Serve the cult's will.")
+ to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs.")
+ else
+ S.mind.store_memory("Serve [U.real_name], your creator.")
+ to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help them succeed in their goals at all costs.")
if(vic && U)
to_chat(U, "Capture successful!: [T.real_name]'s soul has been ripped from [U.p_their()] body and stored within the soul stone.")
if(isrobot(T))//Robots have to dust or else they spill out an empty robot brain, and unequiping them spills robot components that shouldn't spawn.
diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm
index 4b512297ffd..12804cfcc88 100644
--- a/code/game/machinery/poolcontroller.dm
+++ b/code/game/machinery/poolcontroller.dm
@@ -28,21 +28,21 @@
/obj/machinery/poolcontroller/invisible/sea
name = "Sea Controller"
desc = "A controller for the underwater portion of the sea. Players shouldn't see this."
- deep_water = TRUE
+ deep_water = TRUE
-/obj/machinery/poolcontroller/Initialize(mapload)
- var/contents_loop = linked_area
+/obj/machinery/poolcontroller/Initialize(mapload)
+ var/contents_loop = linked_area
if(!linked_area)
contents_loop = range(srange, src)
for(var/turf/T in contents_loop)
if(istype(T, /turf/simulated/floor/beach/water))
var/turf/simulated/floor/beach/water/W = T
- W.linkedcontroller = src
+ W.linkedcontroller = src
linkedturfs += T
else if(istype(T, /turf/unsimulated/beach/water))
var/turf/unsimulated/beach/water/W = T
- W.linkedcontroller = src
+ W.linkedcontroller = src
linkedturfs += T
. = ..()
@@ -121,7 +121,7 @@
return //Has internals, no drowning
if((NO_BREATHE in drownee.dna.species.species_traits) || (BREATHLESS in drownee.mutations))
return //doesn't breathe, no drowning
- if(isskrell(drownee) || isneara(drownee))
+ if(HAS_TRAIT(drownee,TRAIT_WATERBREATH))
return //fish things don't drown
if(drownee.stat == DEAD) //Dead spacemen don't drown more
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index eb3052dd909..eecdc0e4f4a 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -8,6 +8,7 @@ var/const/SAFETY_COOLDOWN = 100
layer = MOB_LAYER+1 // Overhead
anchored = 1
density = 1
+ damage_deflection = 10
var/safety_mode = 0 // Temporarily stops machine if it detects a mob
var/icon_name = "grinder-o"
var/blood = 0
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
index 5b5f483b94f..aacd605b730 100644
--- a/code/game/mecha/equipment/tools/medical_tools.dm
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -316,40 +316,38 @@
var/mob/originaloccupant = chassis.occupant
spawn(0)
src = null //if src is deleted, still process the syringe
- for(var/i=0, i<6, i++)
+ var/max_range = 6
+ for(var/i=0, i [M] was hit by the syringe!")
- if(M.can_inject(null, TRUE))
- if(mechsyringe.reagents)
- for(var/datum/reagent/A in mechsyringe.reagents.reagent_list)
- R += A.id + " ("
- R += num2text(A.volume) + "),"
- add_attack_logs(originaloccupant, M, "Shot with [src] containing [R], transferred [mechsyringe.reagents.total_volume] units")
- mechsyringe.icon_state = initial(mechsyringe.icon_state)
- mechsyringe.icon = initial(mechsyringe.icon)
- mechsyringe.reagents.reaction(M, INGEST)
- mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume)
- M.take_organ_damage(2)
- break
- else if(mechsyringe.loc == trg)
- mechsyringe.icon_state = initial(mechsyringe.icon_state)
- mechsyringe.icon = initial(mechsyringe.icon)
- mechsyringe.update_icon()
- break
- else
- mechsyringe.icon_state = initial(mechsyringe.icon_state)
- mechsyringe.icon = initial(mechsyringe.icon)
- mechsyringe.update_icon()
+ if(!step_towards(mechsyringe,trg))
+ break
+
+ var/list/mobs = new
+ for(var/mob/living/carbon/M in mechsyringe.loc)
+ mobs += M
+ var/mob/living/carbon/M = safepick(mobs)
+ if(M)
+ var/R
+ mechsyringe.visible_message(" [M] was hit by the syringe!")
+ if(M.can_inject(null, TRUE))
+ if(mechsyringe.reagents)
+ for(var/datum/reagent/A in mechsyringe.reagents.reagent_list)
+ R += A.id + " ("
+ R += num2text(A.volume) + "),"
+ add_attack_logs(originaloccupant, M, "Shot with [src] containing [R], transferred [mechsyringe.reagents.total_volume] units")
+ mechsyringe.reagents.reaction(M, INGEST)
+ mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume)
+ M.take_organ_damage(2)
+ break
+ else if(mechsyringe.loc == trg)
break
sleep(1)
+ if(mechsyringe)
+ // Revert the syringe icon to normal one once it stops flying.
+ mechsyringe.icon_state = initial(mechsyringe.icon_state)
+ mechsyringe.icon = initial(mechsyringe.icon)
+ mechsyringe.update_icon()
return 1
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 7dc1a97a735..9f8c877aa24 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -12,7 +12,7 @@
var/heal_brute = 0
var/heal_burn = 0
var/self_delay = 20
- var/unique_handling = 0 //some things give a special prompt, do we want to bypass some checks in parent?
+ var/unique_handling = FALSE //some things give a special prompt, do we want to bypass some checks in parent?
var/stop_bleeding = 0
var/healverb = "bandage"
@@ -31,28 +31,20 @@
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
if(!H.can_inject(user, TRUE))
- return 1
+ return TRUE
if(!affecting)
to_chat(user, "That limb is missing!")
- return 1
+ return TRUE
if(affecting.is_robotic())
to_chat(user, "This can't be used on a robotic limb.")
- return 1
-
- if(stop_bleeding)
- if(H.bleedsuppress)
- to_chat(user, "[H]'s bleeding is already bandaged!")
- return 1
- else if(!H.bleed_rate)
- to_chat(user, "[H] isn't bleeding!")
- return 1
+ return TRUE
if(M == user && !unique_handling)
user.visible_message("[user] starts to apply [src] on [H]...")
if(!do_mob(user, H, self_delay))
- return 1
+ return TRUE
return
if(isanimal(M))
@@ -123,6 +115,7 @@
desc = "Some sterile gauze to wrap around bloody stumps."
icon_state = "gauze"
origin_tech = "biotech=2"
+ heal_brute = 10
stop_bleeding = 1800
/obj/item/stack/medical/bruise_pack/attackby(obj/item/I, mob/user, params)
@@ -140,13 +133,13 @@
/obj/item/stack/medical/bruise_pack/attack(mob/living/M, mob/user)
if(..())
- return 1
+ return TRUE
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
- if(affecting.open == 0)
+ if(affecting.open == FALSE)
affecting.germ_level = 0
if(stop_bleeding)
@@ -187,6 +180,7 @@
icon_state = "ointment"
origin_tech = "biotech=2"
healverb = "salve"
+ heal_burn = 10
/obj/item/stack/medical/ointment/attack(mob/living/M, mob/user)
if(..())
@@ -196,7 +190,7 @@
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
- if(affecting.open == 0)
+ if(affecting.open == FALSE)
affecting.germ_level = 0
heal(H, user)
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 71d5e36badf..0ad64e24f23 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -1069,6 +1069,22 @@ obj/item/toy/cards/deck/syndicate/black
name = "tuxedo cat plushie"
icon_state = "tuxedocat"
+/obj/item/toy/plushie/voxplushie
+ name = "vox plushie"
+ desc = "A stitched-together vox, fresh from the skipjack. Press its belly to hear it skree!"
+ icon_state = "plushie_vox"
+ item_state = "plushie_vox"
+ var/cooldown = 0
+
+/obj/item/toy/plushie/voxplushie/attack_self(mob/user)
+ if(!cooldown)
+ playsound(user, 'sound/voice/shriek1.ogg', 10, 0)
+ visible_message("Skreee!")
+ cooldown = 1
+ spawn(30) cooldown = 0
+ return
+ ..()
+
//New generation TG plushies
/obj/item/toy/plushie/lizardplushie
diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm
index 4d36c640784..4cc4cb948ce 100644
--- a/code/game/objects/items/weapons/manuals.dm
+++ b/code/game/objects/items/weapons/manuals.dm
@@ -18,7 +18,7 @@
-
+