diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index c8a4d91038e..86e85da4fb0 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -135,6 +135,7 @@ var/global/list/bad_blocks[0] // FIXME: Species-specific defaults pls var/obj/item/organ/external/head/H = character.get_organ("head") var/obj/item/organ/internal/eyes/eyes_organ = character.get_int_organ(/obj/item/organ/internal/eyes) + var/datum/species/S = character.species /*// Body Accessory if(!character.body_accessory) @@ -170,7 +171,11 @@ var/global/list/bad_blocks[0] SetUIValueRange(DNA_UI_SKIN_TONE, 35-character.s_tone, 220, 1) // Value can be negative. - SetUIState(DNA_UI_GENDER, character.gender!=MALE, 1) + if(S.has_gender) + SetUIState(DNA_UI_GENDER, character.gender!=MALE, 1) + else + SetUIState(DNA_UI_GENDER, pick(0,1), 1) + /*SetUIValueRange(DNA_UI_BACC_STYLE, bodyacc, facial_hair_styles_list.len, 1)*/ SetUIValueRange(DNA_UI_HEAD_MARK_STYLE, head_marks, marking_styles_list.len, 1) SetUIValueRange(DNA_UI_BODY_MARK_STYLE, body_marks, marking_styles_list.len, 1) diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index c92b75cafc0..743a8ebbe5c 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -132,6 +132,7 @@ dna.check_integrity() var/mob/living/carbon/human/H = src var/obj/item/organ/external/head/head_organ = H.get_organ("head") + var/datum/species/S = H.species dna.write_head_attributes(head_organ) H.r_skin = dna.GetUIValueRange(DNA_UI_SKIN_R, 255) @@ -144,10 +145,11 @@ H.s_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220) // Value can be negative. - if(dna.GetUIState(DNA_UI_GENDER)) - H.change_gender(FEMALE, 0) - else - H.change_gender(MALE, 0) + if(S.has_gender) + if(dna.GetUIState(DNA_UI_GENDER)) + H.change_gender(FEMALE, 0) + else + H.change_gender(MALE, 0) //Head Markings var/head_marks = dna.GetUIValueRange(DNA_UI_HEAD_MARK_STYLE, marking_styles_list.len) diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 04d1f470327..a849b2576f4 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -279,7 +279,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "You are banned from using custom names and appearances. \ You can continue to adjust your characters, but you will be randomised once you join the game.\
" - dat += "Gender: [gender == MALE ? "Male" : "Female"]
" + dat += "Gender: [gender == MALE ? "Male" : (gender == FEMALE ? "Female" : "Genderless")]" + dat += "
" dat += "Age: [age]
" dat += "Body: (®)
" dat += "Species: [species]
" @@ -1031,6 +1032,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts /datum/preferences/proc/process_link(mob/user, list/href_list) if(!user) return + var/datum/species/S = all_species[species] if(href_list["preference"] == "job") switch(href_list["task"]) if("close") @@ -1266,9 +1268,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts // var/whitelisted = 0 if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it! - for(var/S in whitelisted_species) - if(is_alien_whitelisted(user,S)) - new_species += S + for(var/Spec in whitelisted_species) + if(is_alien_whitelisted(user,Spec)) + new_species += Spec // whitelisted = 1 // if(!whitelisted) // alert(user, "You cannot change your species as you need to be whitelisted. If you wish to be whitelisted contact an admin in-game, on the forums, or on IRC.") @@ -1276,8 +1278,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts new_species += whitelisted_species species = input("Please select a species", "Character Generation", null) in new_species - + var/datum/species/NS = all_species[species] if(prev_species != species) + if(NS.has_gender && gender == PLURAL) + gender = pick(MALE,FEMALE) var/datum/robolimb/robohead if(species == "Machine") var/head_model = "[!rlimb_data["head"] ? "Morpheus Cyberkinetics" : rlimb_data["head"]]" @@ -1315,16 +1319,16 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts m_colours["tail"] = "#000000" // Don't wear another species' underwear! - var/datum/sprite_accessory/S = underwear_list[underwear] - if(!S || !(species in S.species_allowed)) + var/datum/sprite_accessory/SA = underwear_list[underwear] + if(!SA || !(species in SA.species_allowed)) underwear = random_underwear(gender, species) - S = undershirt_list[undershirt] - if(!S || !(species in S.species_allowed)) + SA = undershirt_list[undershirt] + if(!SA || !(species in SA.species_allowed)) undershirt = random_undershirt(gender, species) - S = socks_list[socks] - if(!S || !(species in S.species_allowed)) + SA = socks_list[socks] + if(!SA || !(species in SA.species_allowed)) socks = random_socks(gender, species) //reset skin tone and colour @@ -1402,7 +1406,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("h_style") var/list/valid_hairstyles = list() for(var/hairstyle in hair_styles_list) - var/datum/sprite_accessory/S = hair_styles_list[hairstyle] + var/datum/sprite_accessory/SA = hair_styles_list[hairstyle] if(hairstyle == "Bald") //Just in case. valid_hairstyles += hairstyle @@ -1414,14 +1418,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts else head_model = rlimb_data["head"] var/datum/robolimb/robohead = all_robolimbs[head_model] - if((species in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. + if((species in SA.species_allowed) && robohead.is_monitor && ((SA.models_allowed && (robohead.company in SA.models_allowed)) || !SA.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. valid_hairstyles += hairstyle //Give them their hairstyles if they do. else - if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it. + if(!robohead.is_monitor && ("Human" in SA.species_allowed)) /*If the hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it. But if the user has a robotic humanoid head and the hairstyle can fit humans, let them use it as a wig. */ valid_hairstyles += hairstyle else //If the user is not a species who can have robotic heads, use the default handling. - if(species in S.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list. + if(species in SA.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list. valid_hairstyles += hairstyle var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in valid_hairstyles @@ -1609,14 +1613,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("f_style") var/list/valid_facial_hairstyles = list() for(var/facialhairstyle in facial_hair_styles_list) - var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] + var/datum/sprite_accessory/SA = facial_hair_styles_list[facialhairstyle] if(facialhairstyle == "Shaved") //Just in case. valid_facial_hairstyles += facialhairstyle continue - if(gender == MALE && S.gender == FEMALE) + if(gender == MALE && SA.gender == FEMALE) continue - if(gender == FEMALE && S.gender == MALE) + if(gender == FEMALE && SA.gender == MALE) continue if(species == "Machine") //Species that can use prosthetic heads. var/head_model @@ -1625,14 +1629,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts else head_model = rlimb_data["head"] var/datum/robolimb/robohead = all_robolimbs[head_model] - if((species in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. + if((species in SA.species_allowed) && robohead.is_monitor && ((SA.models_allowed && (robohead.company in SA.models_allowed)) || !SA.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. valid_facial_hairstyles += facialhairstyle //Give them their facial hairstyles if they do. else - if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the facial hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it. + if(!robohead.is_monitor && ("Human" in SA.species_allowed)) /*If the facial hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it. But if the user has a robotic humanoid head and the facial hairstyle can fit humans, let them use it as a wig. */ valid_facial_hairstyles += facialhairstyle else //If the user is not a species who can have robotic heads, use the default handling. - if(species in S.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list. + if(species in SA.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list. valid_facial_hairstyles += facialhairstyle var/new_f_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in valid_facial_hairstyles @@ -1642,12 +1646,12 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("underwear") var/list/valid_underwear = list() for(var/underwear in underwear_list) - var/datum/sprite_accessory/S = underwear_list[underwear] - if(gender == MALE && S.gender == FEMALE) + var/datum/sprite_accessory/SA = underwear_list[underwear] + if(gender == MALE && SA.gender == FEMALE) continue - if(gender == FEMALE && S.gender == MALE) + if(gender == FEMALE && SA.gender == MALE) continue - if(!(species in S.species_allowed)) + if(!(species in SA.species_allowed)) continue valid_underwear[underwear] = underwear_list[underwear] var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in valid_underwear @@ -1657,12 +1661,12 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("undershirt") var/list/valid_undershirts = list() for(var/undershirt in undershirt_list) - var/datum/sprite_accessory/S = undershirt_list[undershirt] - if(gender == MALE && S.gender == FEMALE) + var/datum/sprite_accessory/SA = undershirt_list[undershirt] + if(gender == MALE && SA.gender == FEMALE) continue - if(gender == FEMALE && S.gender == MALE) + if(gender == FEMALE && SA.gender == MALE) continue - if(!(species in S.species_allowed)) + if(!(species in SA.species_allowed)) continue valid_undershirts[undershirt] = undershirt_list[undershirt] var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in valid_undershirts @@ -1673,12 +1677,12 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("socks") var/list/valid_sockstyles = list() for(var/sockstyle in socks_list) - var/datum/sprite_accessory/S = socks_list[sockstyle] - if(gender == MALE && S.gender == FEMALE) + var/datum/sprite_accessory/SA = socks_list[sockstyle] + if(gender == MALE && SA.gender == FEMALE) continue - if(gender == FEMALE && S.gender == MALE) + if(gender == FEMALE && SA.gender == MALE) continue - if(!(species in S.species_allowed)) + if(!(species in SA.species_allowed)) continue valid_sockstyles[sockstyle] = socks_list[sockstyle] var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in valid_sockstyles @@ -1909,10 +1913,20 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts toggles ^= DONATOR_PUBLIC if("gender") - if(gender == MALE) - gender = FEMALE + if(!S.has_gender) + var/newgender = input(user, "Choose Gender:") as null|anything in list("Male", "Female", "Genderless") + switch(newgender) + if("Male") + gender = MALE + if("Female") + gender = FEMALE + if("Genderless") + gender = PLURAL else - gender = MALE + if(gender == MALE) + gender = FEMALE + else + gender = MALE underwear = random_underwear(gender) if("hear_adminhelps") @@ -2153,7 +2167,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.backbag = backbag //Debugging report to track down a bug, which randomly assigned the plural gender to people. - if(character.gender in list(PLURAL, NEUTER)) + if(S.has_gender && (character.gender in list(PLURAL, NEUTER))) if(isliving(src)) //Ghosts get neuter by default message_admins("[key_name_admin(character)] has spawned with their gender as plural or neuter. Please notify coders.") character.change_gender(MALE) diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index b4a589f35a5..02d246b4f70 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -270,6 +270,7 @@ gear = params2list(query.item[65]) //Sanitize + var/datum/species/SP = all_species[species] metadata = sanitize_text(metadata, initial(metadata)) real_name = reject_bad_name(real_name, 1) if(isnull(species)) species = "Human" @@ -278,7 +279,7 @@ if(isnull(speciesprefs)) speciesprefs = initial(speciesprefs) if(!real_name) real_name = random_name(gender,species) be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name)) - gender = sanitize_gender(gender) + gender = sanitize_gender(gender, FALSE, !SP.has_gender) age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) r_hair = sanitize_integer(r_hair, 0, 255, initial(r_hair)) g_hair = sanitize_integer(g_hair, 0, 255, initial(g_hair)) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index ad1ab28c435..3cedf2d1f3f 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -16,7 +16,7 @@ /mob/living/carbon/human/proc/change_gender(var/new_gender, var/update_dna = 1) var/obj/item/organ/external/head/H = organs_by_name["head"] - if(gender == new_gender) + if(gender == new_gender || (gender == PLURAL && species.has_gender)) return gender = new_gender @@ -488,4 +488,4 @@ valid_alt_heads += alternate_head - return valid_alt_heads \ No newline at end of file + return valid_alt_heads diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index ffd759b3295..93d9a49d6df 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -33,7 +33,7 @@ var/msg = "*---------*\nThis is " - if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender + if((skipjumpsuit && skipface)) //big suits/masks/helmets make it hard to tell their gender t_He = "They" t_his = "their" t_him = "them" @@ -51,6 +51,12 @@ t_He = "She" t_his = "her" t_him = "her" + if(PLURAL) + t_He = "They" + t_his = "their" + t_him = "them" + t_has = "have" + t_is = "are" msg += "[name]" @@ -494,7 +500,7 @@ msg += "Medical records: \[View\] \[Add comment\]\n" - if(print_flavor_text() && !skipface) + if(print_flavor_text() && !skipface) msg += "[print_flavor_text()]\n" msg += "*---------*" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index ed578e20dd1..79dbaf0a1cd 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1479,6 +1479,7 @@ /mob/living/carbon/human/proc/set_species(var/new_species, var/default_colour, var/delay_icon_update = 0) var/datum/species/oldspecies = species + var/datum/species/NS = all_species[new_species] if(!dna) if(!new_species) new_species = "Human" @@ -1498,6 +1499,8 @@ if(species.default_language) remove_language(species.default_language) + if(gender == PLURAL && NS.has_gender) + change_gender(pick(MALE,FEMALE)) species.handle_pre_change(src) species = all_species[new_species] diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index fec4da6fae4..4e0cf476879 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -110,6 +110,7 @@ var/show_ssd = 1 var/virus_immune var/can_revive_by_healing // Determines whether or not this species can be revived by simply healing them + var/has_gender = TRUE //Death vars. var/death_message = "seizes up and falls limp, their eyes dead and lifeless..." diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index b7ca9d991d1..b39e880e718 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -899,6 +899,7 @@ default_hair = "Blue IPC Screen" virus_immune = 1 can_revive_by_healing = 1 + has_gender = FALSE reagent_tag = PROCESS_SYN male_scream_sound = 'sound/goonstation/voice/robot_scream.ogg' female_scream_sound = 'sound/goonstation/voice/robot_scream.ogg' @@ -911,7 +912,8 @@ has_organ = list( "brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain, "cell" = /obj/item/organ/internal/cell, - "optics" = /obj/item/organ/internal/eyes/optical_sensor //Default darksight of 2. + "optics" = /obj/item/organ/internal/eyes/optical_sensor, //Default darksight of 2. + "charger" = /obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord ) vision_organ = /obj/item/organ/internal/eyes/optical_sensor diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 21636465d4a..95738cd6354 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -223,6 +223,7 @@ data["specimen"] = owner.species.name data["gender"] = owner.gender + data["has_gender"] = owner.species.has_gender data["change_race"] = can_change(APPEARANCE_RACE) if(data["change_race"]) var/species[0] diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 56da9cf9b07..0c6965c0e06 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -640,6 +640,9 @@ (istype(W, /obj/item/device/multitool) || \ istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/assembly/signaler))) return src.attack_hand(user) + if(W.flags & NOBLUDGEON) + return + user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) user.visible_message("The [src.name] has been hit with the [W.name] by [user.name]!", \ "You hit the [src.name] with your [W.name]!", \ @@ -667,36 +670,6 @@ if(!user) return src.add_fingerprint(user) - //Synthetic human mob goes here. - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(H.get_int_organ(/obj/item/organ/internal/cell) && H.a_intent == I_GRAB) - if(emagged || stat & BROKEN) - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - to_chat(H, "The APC power currents surge erratically, damaging your chassis!") - H.adjustFireLoss(10,0) - else if(src.cell && src.cell.charge > 0) - if(H.nutrition < NUTRITION_LEVEL_WELL_FED) - if(src.cell.charge >= 500) - H.nutrition += 50 - src.cell.charge -= 500 - else - H.nutrition += src.cell.charge/10 - src.cell.charge = 0 - - to_chat(user, "You slot your fingers into the APC interface and siphon off some of the stored charge for your own use.") - if(src.cell.charge < 0) - src.cell.charge = 0 - if(H.nutrition > NUTRITION_LEVEL_WELL_FED + 50) - H.nutrition = NUTRITION_LEVEL_WELL_FED + 50 - src.charging = 1 - else - to_chat(user, "You are already fully charged.") - else - to_chat(user, "There is no charge to draw from that APC.") - return if(usr == user && opened && (!issilicon(user))) if(cell) diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 153f169efca..ffd0b4f0b1e 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -8,17 +8,17 @@ var/implant_overlay tough = 1 //not easyly broken by combat damage sterile = 1 //not very germy + robotic = 2 // these are cybernetic after all /obj/item/organ/internal/cyberimp/New(var/mob/M = null) - if(iscarbon(M)) - src.insert(M) + . = ..() if(implant_overlay) var/image/overlay = new /image(icon, implant_overlay) overlay.color = implant_color overlays |= overlay - return ..() - +/obj/item/organ/internal/cyberimp/emp_act() + return // These shouldn't be hurt by EMPs in the standard way //[[[[BRAIN]]]] @@ -270,9 +270,15 @@ var/lasthand = null /obj/item/organ/internal/cyberimp/chest/arm_mod/ui_action_click() + toggle_item() + +/obj/item/organ/internal/cyberimp/chest/arm_mod/proc/toggle_item() if(overloaded)//ensure the implant isn't broken to_chat(owner, "The implant doesn't respond. It seems to be broken...") return + owner.changeNext_move(CLICK_CD_MELEE) + if(owner.next_move < world.time) + return // No spam if(out)//check if the owner has the item out already owner.unEquip(holder, 1)//if he does, take it away. then, holder.loc = null//stash it in nullspace @@ -297,6 +303,9 @@ holder.loc = null out = 0 owner.visible_message("[holder] forcibly retracts into [owner]'s arm.") + overload() // Make sure this doesn't happen again + +/obj/item/organ/internal/cyberimp/chest/arm_mod/proc/overload() owner.visible_message("A loud bang comes from [owner]...") playsound(get_turf(owner), 'sound/effects/bang.ogg', 100, 1) to_chat(owner, "You feel an explosion erupt inside you as your chest implant breaks. Is it hot in here?") @@ -312,7 +321,7 @@ limb.droplimb(0, DROPLIMB_EDGE) owner.say("I HAVE BEEN DISARMED!!!") owner.adjustFireLoss(25)//severely injure him! - overloaded = 1//then make sure this can't happen again by breaking the implant. + overloaded = TRUE /obj/item/organ/internal/cyberimp/chest/arm_mod/tase//mounted, self-charging taser! name = "Arm-cannon taser implant" @@ -322,6 +331,7 @@ actions_types = list(/datum/action/item_action/organ_action/toggle) /obj/item/organ/internal/cyberimp/chest/arm_mod/tase/New()//when the implant is created... + ..() holder = new /obj/item/weapon/gun/energy/gun/advtaser/mounted(src)//assign a brand new item to it. (in this case, a gun) /obj/item/organ/internal/cyberimp/chest/arm_mod/lase//mounted, self-charging laser! @@ -332,8 +342,88 @@ actions_types = list(/datum/action/item_action/organ_action/toggle) /obj/item/organ/internal/cyberimp/chest/arm_mod/lase/New() + ..() holder = new /obj/item/weapon/gun/energy/laser/mounted(src) +// lets make IPCs even *more* vulnerable to EMPs! +/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord + name = "APC-compatible power adapter implant" + desc = "An implant commonly installed inside IPCs in order to allow them to easily collect energy from their environment" + origin_tech = "materials=3;biotech=2;powerstorage=3" + slot = "shoulders2" + actions_types = list(/datum/action/item_action/organ_action/toggle) + + +/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/New() + ..() + holder = new /obj/item/apc_powercord(src) + +/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/overload() + // To allow repair via nanopaste/screwdriver + // also so IPCs don't also catch on fire and fall even more apart upon EMP + damage = 1 + overloaded = TRUE + +/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/surgeryize() + if(overloaded && owner) + to_chat(owner, "Your [src] feels functional again.") + overloaded = FALSE + + +/obj/item/apc_powercord + name = "power cable" + desc = "Insert into a nearby APC to draw power from it." + icon = 'icons/obj/power.dmi' + icon_state = "wire1" + flags = NODROP | NOBLUDGEON + +/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag) + return ..() + user.changeNext_move(CLICK_CD_MELEE) + var/obj/machinery/power/apc/A = target + var/mob/living/carbon/human/H = user + if(H.get_int_organ(/obj/item/organ/internal/cell)) + if(A.emagged || A.stat & BROKEN) + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(3, 1, A) + s.start() + to_chat(H, "The APC power currents surge erratically, damaging your chassis!") + H.adjustFireLoss(10,0) + else if(A.cell && A.cell.charge > 0) + if(H.nutrition >= NUTRITION_LEVEL_WELL_FED) + to_chat(user, "You are already fully charged!") + else + addtimer(src, "powerdraw_loop", 0, TRUE, A, H) + else + to_chat(user, "There is no charge to draw from that APC.") + else + to_chat(user, "You lack a cell in which to store charge!") + +/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H) + H.visible_message("[H] inserts a power connector into \the [A].", "You begin to draw power from \the [A].") + while(do_after(H, 10, target = A)) + if(loc != H) + to_chat(H, "You must keep your connector out while charging!") + break + if(A.cell.charge == 0) + to_chat(H, "\The [A] has no more charge.") + break + A.charging = 1 + if(A.cell.charge >= 500) + H.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 + A.cell.charge = 0 + to_chat(H, "You siphon off the last of \the [A]'s charge.") + break + if(H.nutrition > NUTRITION_LEVEL_WELL_FED) + to_chat(H, "You are now fully charged.") + break + H.visible_message("[H] unplugs from \the [A].", "You unplug from \the [A].") + //BOX O' IMPLANTS /obj/item/weapon/storage/box/cyber_implants diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 8de7cccd2d6..0906b3c63c5 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -11,9 +11,9 @@ var/non_primary = 0 /obj/item/organ/internal/New(var/mob/living/carbon/holder) + ..() if(istype(holder)) insert(holder) - ..() /obj/item/organ/internal/Destroy() if(owner) @@ -412,7 +412,8 @@ colourmatrix = null dark_view = 2 ..() //Make sure the organ's got the robotic status indicators before updating the client colour. - owner.update_client_colour(0) //Since both mechassisted and mechanical eyes give dark_view of 2 and full colour vision atm, just having this here is fine as mechassist() will call it anyway. + if(owner) + owner.update_client_colour(0) //Since both mechassisted and mechanical eyes give dark_view of 2 and full colour vision atm, just having this here is fine as mechassist() will call it anyway. /obj/item/organ/internal/mechassist() ..() //Go back, call robotize(), adjust the robotic status indicators and the organ damage parameters. diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index d3d5345cb0b..e1dc252412d 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -398,11 +398,16 @@ return var/obj/item/organ/external/affected = target.get_organ(target_zone) + var/found_damaged_organ = FALSE for(var/obj/item/organ/internal/I in affected.internal_organs) - if(I && I.damage > 0) - if(I.robotic >= 2) - user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \ - "You start mending the damage to [target]'s [I.name]'s mechanisms." ) + if(I && I.damage > 0 && I.robotic >= 2) + user.visible_message("[user] starts mending the damage to [target]'s [I.name]'s mechanisms.", \ + "You start mending the damage to [target]'s [I.name]'s mechanisms.") + found_damaged_organ = TRUE + + if(!found_damaged_organ) + to_chat(user, "There are no damaged components in [affected].") + return -1 target.custom_pain("The pain in your [affected.name] is living hell!",1) @@ -425,6 +430,7 @@ user.visible_message(" [user] repairs [target]'s [I.name] with [tool].", \ " You repair [target]'s [I.name] with [tool]." ) I.damage = 0 + I.surgeryize() else if(current_type == "insert") var/obj/item/organ/internal/I = tool diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl index 47a3ce113e2..5e705b2fe46 100644 --- a/nano/templates/appearance_changer.tmpl +++ b/nano/templates/appearance_changer.tmpl @@ -19,6 +19,9 @@
{{:helper.link('Male', null, { 'gender' : 'male'}, null, data.gender == 'male' ? 'selected' : null)}} {{:helper.link('Female', null, { 'gender' : 'female'}, null, data.gender == 'female' ? 'selected' : null)}} + {{if !data.has_gender}} + {{:helper.link('Genderless', null, { 'gender' : 'plural'}, null, data.gender == 'plural' ? 'selected' : null)}} + {{/if}}
{{/if}}