diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index bcc337ec570..2166c674028 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -165,7 +165,7 @@ Implant Specifics:
"}
message_admins("Explosive implant triggered in [T] ([T.key]). (JMP) ")
log_game("Explosive implant triggered in [T] ([T.key]).")
need_gib = 1
-
+
if(ishuman(imp_in))
if (elevel == "Localized Limb")
if(part) //For some reason, small_boom() didn't work. So have this bit of working copypaste.
@@ -194,7 +194,7 @@ Implant Specifics:
"}
if(need_gib)
imp_in.gib()
-
+
var/turf/t = get_turf(imp_in)
if(t)
@@ -501,3 +501,4 @@ the implant may become unstable and either pre-maturely inject the subject or si
/obj/item/weapon/implant/cortical
name = "cortical stack"
desc = "A fist-sized mass of biocircuits and chips."
+ icon_state = "implant_evil"
\ No newline at end of file
diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm
index f1e6204d223..d00435e1fca 100644
--- a/code/modules/admin/verbs/vox_raiders.dm
+++ b/code/modules/admin/verbs/vox_raiders.dm
@@ -68,19 +68,6 @@ var/global/vox_tick = 1
W.handle_item_insertion(C)
spawn_money(rand(50,150)*10,W)
equip_to_slot_or_del(W, slot_wear_id)
-
- var/obj/item/weapon/implant/cortical/I = new(src)
- I.imp_in = src
- I.implanted = 1
- var/datum/organ/external/affected = src.get_organ("head")
- affected.implants += I
- I.part = affected
-
- if(ticker.mode && ( istype( ticker.mode,/datum/game_mode/heist ) ) )
- var/datum/game_mode/heist/M = ticker.mode
- M.cortical_stacks += I
- M.raiders[mind] = I
-
vox_tick++
if (vox_tick > 4) vox_tick = 1
diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm
index fa02150ab38..4b8d16dfbb5 100644
--- a/code/modules/mob/living/carbon/brain/posibrain.dm
+++ b/code/modules/mob/living/carbon/brain/posibrain.dm
@@ -46,6 +46,18 @@
C.prefs.be_special ^= BE_PAI
+ transfer_identity(var/mob/living/carbon/H)
+ name = "positronic brain ([H])"
+ brainmob.name = H.real_name
+ brainmob.real_name = H.real_name
+ brainmob.dna = H.dna
+ brainmob.timeofhostdeath = H.timeofdeath
+ brainmob.mind.assigned_role = "Positronic Brain"
+ if(H.mind)
+ H.mind.transfer_to(brainmob)
+ brainmob << "\blue You feel slightly disoriented. That's normal when you're just a metal cube."
+ icon_state = "posibrain-occupied"
+ return
proc/transfer_personality(var/mob/candidate)
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index 289ecf67ace..fb82ca3e7ed 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -53,10 +53,14 @@
/mob/living/carbon/human/death(gibbed)
if(stat == DEAD) return
if(healths) healths.icon_state = "health5"
+
stat = DEAD
dizziness = 0
jitteriness = 0
+ //Handle species-specific deaths.
+ if(species) species.handle_death(src)
+
//Handle brain slugs.
var/datum/organ/external/head = get_organ("head")
var/mob/living/simple_animal/borer/B
@@ -105,6 +109,8 @@
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
return ..(gibbed)
+
+
/mob/living/carbon/human/proc/makeSkeleton()
if(SKELETON in src.mutations) return
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index aa381c8c3de..0988430a6b0 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1275,6 +1275,7 @@ mob/living/carbon/human/yank_out_object()
update_icons()
if(species)
+ species.handle_post_spawn(src)
return 1
else
return 0
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 40db476eba3..742cbdd641f 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -40,12 +40,18 @@
/mob/living/carbon/human/adjustBruteLoss(var/amount)
+ if(species && species.brute_mod)
+ amount = amount*species.brute_mod
+
if(amount > 0)
take_overall_damage(amount, 0)
else
heal_overall_damage(-amount, 0)
/mob/living/carbon/human/adjustFireLoss(var/amount)
+ if(species && species.burn_mod)
+ amount = amount*species.burn_mod
+
if(amount > 0)
take_overall_damage(0, amount)
else
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index b2a2180eadc..e119d1ff069 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -286,7 +286,7 @@
proc/breathe()
if(reagents.has_reagent("lexorin")) return
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
- if(species && species.flags & NO_BREATHE) return
+ if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return
var/datum/organ/internal/lungs/L = internal_organs["lungs"]
L.process()
@@ -639,7 +639,15 @@
pressure_alert = 0
else if(adjusted_pressure >= species.hazard_low_pressure)
pressure_alert = -1
+
+ if(species && species.flags & IS_SYNTHETIC)
+ bodytemperature += 0.5 * TEMPERATURE_DAMAGE_COEFFICIENT //Synthetics suffer overheating in a vaccuum. ~Z
+
else
+
+ if(species && species.flags & IS_SYNTHETIC)
+ bodytemperature += 1 * TEMPERATURE_DAMAGE_COEFFICIENT
+
if( !(COLD_RESISTANCE in mutations))
adjustBruteLoss( LOW_PRESSURE_DAMAGE )
pressure_alert = -2
diff --git a/code/modules/mob/living/carbon/monkey/diona.dm b/code/modules/mob/living/carbon/monkey/diona.dm
index d26de1f9a94..f32aa43a9b9 100644
--- a/code/modules/mob/living/carbon/monkey/diona.dm
+++ b/code/modules/mob/living/carbon/monkey/diona.dm
@@ -30,7 +30,7 @@
..()
/obj/item/weapon/holder/process()
- if(!loc) return
+ if(!loc) Del(src)
if(istype(loc,/turf) || !(contents.len))
for(var/mob/M in contents)
@@ -54,12 +54,19 @@
//Let people pick the little buggers up.
if(M.a_intent == "help")
- var/obj/item/weapon/holder/diona/D = new(loc)
- src.loc = D
- D.name = loc.name
- D.attack_hand(M)
- M << "You scoop up [src]."
- src << "[M] scoops you up."
+ if(M.species && M.species.name == "Diona")
+ M << "You feel your being twine with that of [src] as it merges with your biomass."
+ src << "You feel your being twine with that of [M] as you merge with its biomass."
+ src.verbs += /mob/living/carbon/monkey/diona/proc/split
+ src.verbs -= /mob/living/carbon/monkey/diona/proc/merge
+ src.loc = M
+ else
+ var/obj/item/weapon/holder/diona/D = new(loc)
+ src.loc = D
+ D.name = loc.name
+ D.attack_hand(M)
+ M << "You scoop up [src]."
+ src << "[M] scoops you up."
return
..()
@@ -71,9 +78,59 @@
dna.mutantrace = "plant"
greaterform = "Diona"
add_language("Rootspeak")
+ src.verbs += /mob/living/carbon/monkey/diona/proc/merge
//Verbs after this point.
+/mob/living/carbon/monkey/diona/proc/merge()
+
+ set category = "Diona"
+ set name = "Merge with gestalt"
+ set desc = "Merge with another diona."
+
+ if(istype(src.loc,/mob/living/carbon))
+ src.verbs -= /mob/living/carbon/monkey/diona/proc/merge
+ return
+
+ var/list/choices = list()
+ for(var/mob/living/carbon/C in view(1,src))
+
+ if(!(src.Adjacent(C)) || !(C.client)) continue
+
+ if(istype(C,/mob/living/carbon/human))
+ var/mob/living/carbon/human/D = C
+ if(D.species && D.species.name == "Diona")
+ choices += C
+
+ var/mob/living/M = input(src,"Who do you wish to merge with?") in null|choices
+
+ if(!M || !src || !(src.Adjacent(M))) return
+
+ if(istype(M,/mob/living/carbon/human))
+ M << "You feel your being twine with that of [src] as it merges with your biomass."
+ src << "You feel your being twine with that of [M] as you merge with its biomass."
+ src.loc = M
+ src.verbs += /mob/living/carbon/monkey/diona/proc/split
+ src.verbs -= /mob/living/carbon/monkey/diona/proc/merge
+ else
+ return
+
+/mob/living/carbon/monkey/diona/proc/split()
+
+ set category = "Diona"
+ set name = "Split from gestalt"
+ set desc = "Split away from your gestalt as a lone nymph."
+
+ if(!(istype(src.loc,/mob/living/carbon)))
+ src.verbs -= /mob/living/carbon/monkey/diona/proc/split
+ return
+
+ src.loc << "You feel a pang of loss as [src] splits away from your biomass."
+ src << "You wiggle out of the depths of [src.loc]'s biomass and plop to the ground."
+ src.loc = get_turf(src)
+ src.verbs -= /mob/living/carbon/monkey/diona/proc/split
+ src.verbs += /mob/living/carbon/monkey/diona/proc/merge
+
/mob/living/carbon/monkey/diona/verb/fertilize_plant()
set category = "Diona"
@@ -130,6 +187,7 @@
src << "You have not yet consumed enough to grow..."
return
+ src.split()
src.visible_message("\red [src] begins to shift and quiver, and erupts in a shower of shed bark and twigs!","\red You begin to shift and quiver, then erupt in a shower of shed bark and twigs, attaining your adult form!")
var/mob/living/carbon/human/adult = new(get_turf(src.loc))
@@ -172,6 +230,9 @@
src.visible_message("\red [src] flicks out a feeler and neatly steals a sample of [M]'s blood.","\red You flick out a feeler and neatly steal a sample of [M]'s blood.")
donors += M.real_name
+ for(var/datum/language/L in M.languages)
+ languages += L
+
spawn(25)
update_progression()
@@ -183,10 +244,7 @@
if(donors.len == 5)
ready_evolve = 1
src << "\green You feel ready to move on to your next stage of growth."
- else if(donors.len == 2)
- universal_understand = 1
- src << "\green You feel your awareness expand, and realize you know how to understand the creatures around you."
- else if(donors.len == 4)
+ else if(donors.len == 3)
universal_speak = 1
src << "\green You feel your awareness expand, and realize you know how to speak with the creatures around you."
else
diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm
index cd6939831a0..2eb21bfb480 100644
--- a/code/modules/mob/living/carbon/species.dm
+++ b/code/modules/mob/living/carbon/species.dm
@@ -32,8 +32,8 @@
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure.
- var/brute_resist // Physical damage reduction.
- var/burn_resist // Burn damage reduction.
+ var/brute_mod = null // Physical damage reduction/malus.
+ var/burn_mod = null // Burn damage reduction/malus.
var/flags = 0 // Various specific features.
@@ -42,6 +42,18 @@
var/blood_color = "#A10808" //Red.
var/flesh_color = "#FFC896" //Pink.
+/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
+
+ if(flags & IS_SYNTHETIC)
+ for(var/datum/organ/external/E in H.organs)
+ if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue
+ E.status |= ORGAN_ROBOT
+
+ return
+
+/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
+ return
+
/datum/species/human
name = "Human"
language = "Sol Common"
@@ -131,9 +143,31 @@
blood_color = "#2299FC"
flesh_color = "#808D11"
+/datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H)
+
+ var/datum/organ/external/affected = H.get_organ("head")
+
+ //To avoid duplicates.
+ for(var/obj/item/weapon/implant/cortical/imp in H.contents)
+ affected.implants -= imp
+ Del(imp)
+
+ var/obj/item/weapon/implant/cortical/I = new(H)
+ I.imp_in = H
+ I.implanted = 1
+ affected.implants += I
+ I.part = affected
+
+ if(ticker.mode && ( istype( ticker.mode,/datum/game_mode/heist ) ) )
+ var/datum/game_mode/heist/M = ticker.mode
+ M.cortical_stacks += I
+ M.raiders[H.mind] = I
+
+ return ..()
+
/datum/species/diona
name = "Diona"
- icobase = 'icons/mob/human_races/r_plant.dmi'
+ icobase = 'icons/mob/human_races/r_diona.dmi'
deform = 'icons/mob/human_races/r_def_plant.dmi'
language = "Rootspeak"
attack_verb = "slash"
@@ -156,3 +190,49 @@
blood_color = "#004400"
flesh_color = "#907E4A"
+/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H)
+
+ H.gender = NEUTER
+
+/datum/species/diona/handle_death(var/mob/living/carbon/human/H)
+
+ var/mob/living/carbon/monkey/diona/S = new(get_turf(H))
+
+ if(H.mind)
+ H.mind.transfer_to(S)
+ S.key = H
+
+ for(var/mob/living/carbon/monkey/diona/D in H.contents)
+ if(D.client)
+ D.loc = H.loc
+ else
+ Del(D)
+
+ H.visible_message("\red[H] splits apart with a wet slithering noise!")
+
+/datum/species/machine
+ name = "Machine"
+ icobase = 'icons/mob/human_races/r_machine.dmi'
+ deform = 'icons/mob/human_races/r_machine.dmi'
+ language = "Tradeband"
+ punch_damage = 2
+
+ eyes = "blank_eyes"
+ brute_mod = 1.5
+ burn_mod = 1.5
+
+ warning_low_pressure = 50
+ hazard_low_pressure = 10
+
+ cold_level_1 = 50
+ cold_level_2 = -1
+ cold_level_3 = -1
+
+ heat_level_1 = 2000
+ heat_level_2 = 3000
+ heat_level_3 = 4000
+
+ flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC
+
+ blood_color = "#FFFFFF"
+ flesh_color = "#AAAAAA"
\ No newline at end of file
diff --git a/code/setup.dm b/code/setup.dm
index 7f77df4a9ad..96bc6222087 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -740,6 +740,8 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
#define RAD_ABSORB 2048
#define REQUIRE_LIGHT 4096
+#define IS_SYNTHETIC 8192
+
//Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
#define RESTRICTED 2 // Language can only be accquired by spawning or an admin.