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.