diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 47df198e5b8..3ee7365eaf2 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -7232,7 +7232,7 @@ "cJd" = (/obj/machinery/computer/station_alert,/turf/simulated/floor/plasteel,/area/engine/engineering) "cJe" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/engine/engineering) "cJf" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engine/hardsuitstorage) -"cJg" = (/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/engine/hardsuitstorage) +"cJg" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Storage"; req_access_txt = "11"; req_one_access_txt = null},/turf/simulated/floor/plasteel,/area/engine/hardsuitstorage) "cJh" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/turf/simulated/floor/plasteel{tag = "icon-whitegreen (WEST)"; icon_state = "whitegreen"; dir = 8},/area/medical/virology) "cJi" = (/obj/machinery/camera{c_tag = "Engineering Chief Engineer's Office"; dir = 4; network = list("SS13")},/obj/item/device/radio/intercom{name = "station intercom (General)"; pixel_x = -28; pixel_y = 0},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cJj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) @@ -7337,7 +7337,6 @@ "cLe" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cLf" = (/obj/structure/closet/crate,/obj/item/clothing/under/color/lightpurple,/obj/item/weapon/spacecash/c200,/turf/simulated/floor/plating,/area/maintenance/asmaint2) "cLg" = (/obj/effect/spawner/window,/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cLh" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/airlock/glass_engineering{name = "Storage"; req_access_txt = "11"; req_one_access_txt = null},/turf/simulated/floor/plasteel,/area/engine/hardsuitstorage) "cLi" = (/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/cable,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "xenobio4"; name = "Containment Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/xenobiology) "cLj" = (/obj/machinery/door/window/southright{name = "Containment Pen"; req_access_txt = "55"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "xenobio4"; name = "Containment Blast Doors"; opacity = 0},/turf/simulated/floor/engine,/area/toxins/xenobiology) "cLk" = (/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "xenobio4"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable,/turf/simulated/floor/plating,/area/toxins/xenobiology) @@ -8921,7 +8920,7 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikafxaabcFscFtcFtcFucFvcFwcFwcFwcFvcFwcFwcFwcFvcFwcFwcFxcFtcFtcFtcFtcFtcFycFzcFAcFBcFCcFDcFEcFFcFGcfRcwWcFHcDfcvKcvKcvKcFIcEBcECcFJcFKcFLcyrcFNcDucFPcFOcFQcFScFTcSpcFVcFWcFXcFScFYcFZcDwcGacDzcDzcDzcGbcBCcGccGccDFcGdcGecGfcGgcGhcGicGjcGkcGlcGmcGncDOcGocDQcGpcDTcDTcCKcHBcoDcEhclUcyMcyLcyNcFfclUcnkclTcFfclUcyQcyScyRcyTcyTclUcusbGycJOcoAbikckPcxOcxPcxOcGAcxRcqUcGBcJPcJJcqUdlWcGDcwAcwAcwAckPbikbikaabaabbikbikbikbikbikbwocyKcvzbwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikaabbikaabaabcGFaabbikaabcGFaabbikaabcGFaabbikbikbikbikbikbikbikbikcDccDccDccGGcGHcFMcDdcGJcfRcGKcExcExcExcExcGLcExcFGcECcGMcGNcGOcGPcGQcGRcGScGTcGUcGVcGWcGXcGYcGZcHacHbcFYcELcDwcHccHdcDzcDzcHecBCcHfcHgcDFcHhcCAcHicHjcHkcHlcHmcHncHocHpcHocHqaabcCKcCKcCKcCKcCKcHBcoAcEhclUcIJcyVcyYcyXcEecEccEgcEfcHwcGucHZczVcIRcIQclUcusbGycJRcoAbikckPcxOcxOcxOcFjcHEcHFcHGcJScHIcCZcCZcCZcHJcHKcHLcHMbikbikbikaabaabbikbikbikbikbwobwocvzbwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGacGafxaabaabczocHOczqbikczocHOczqbikczocHOczqaabbikbikbikbikbikbikbikaabaabcDccDdcDdcDdcDdcHPcHQcHRcfRcHScfRcfRcEBcHTcfRcECcHUcHVcGOcHWcFNcHXcHYcIacIacIbcIccIdcIedmabRFcIbcIhcIicIjcIkcIlcImcIncIocIpcIqcGfcIrcIscItcIucIvcIwcIxcIycIzcIAcIBcICcIDcDPcDQcIEcIFcIFcCKcHBcoAcEhclUclUclUclUclUcJhcANcBRcJQcMccBScMecMdcMCcBVclUcuscGqcGrcGrcGrcJTcJTcJTcJTcJTcJUcKTcKbcKUcIUczbcIVczbcIWczbcIXcHMbikbikbikbikaabaabbikbikbikbikbwocvzbwoaabaabaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikczocHOczqaabczocHOczqbikczocHOczqbikbikbikaabbikbikbikbikaabaabaabbikbikaabaabcJbcJbcJbcJbcJbcJbcJbcJccJbcJbcECcJdcJecGOcHWcFNcJfcFNcJgcLhcDtcJicJjcFWcJkcFRcDtcJmcDzcDwcJncJocJpcIncJqcJrcJscJtcJucJvcJwcJtcJxcJycJzcJAcDFcJBcJCcJDcJEaabcEVcJFcJGcJHcCKcHBcoDcKWcKVcKVcKVcKXclUcFacyLcCLcFecyScCMcyTcyTcyScCNclUcuscGvbVibGycKYcKZcoAbikbikckPcJVcJWcJXcJYcJVcJWcJZcKacJVcJWcLackPaabaabaabaabaabaabaabaabaabaabbwocvzbwobwobwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjcbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikczocHOczqaabczocHOczqbikczocHOczqbikbikbikaabbikbikbikbikaabaabaabbikbikaabaabcJbcJbcJbcJbcJbcJbcJbcJccJbcJbcECcJdcJecGOcHWcFNcJfcFNcFNcJgcDtcJicJjcFWcJkcFRcDtcJmcDzcDwcJncJocJpcIncJqcJrcJscJtcJucJvcJwcJtcJxcJycJzcJAcDFcJBcJCcJDcJEaabcEVcJFcJGcJHcCKcHBcoDcKWcKVcKVcKVcKXclUcFacyLcCLcFecyScCMcyTcyTcyScCNclUcuscGvbVibGycKYcKZcoAbikbikckPcJVcJWcJXcJYcJVcJWcJZcKacJVcJWcLackPaabaabaabaabaabaabaabaabaabaabbwocvzbwobwobwobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjcbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikafxaabczocHOczqbikczocHOczqbikczocHOczqaabbikbikbikbikbikbikbikaabaabbikbikaabaabaabcJbcKjcKjcKkcGIcKmcKmcKncKocKocKpcKqcKrcGOcHWcGOcKscGOcGOcGOcDtcKtcKucKvcKwcKxcKycKzcKAcKBcKCcKCcKCcKDcKEcKFcKGcKHcKIcHhcCAcKJcKKcKLcKMcKNcDFcJBcKOcKPcKQcKRcDQcKScIFcIFcCKcHBcoDcEhbVibVibVibYDclUcFgcCOcDXcNDcyScPocPMcyTcPVcPQclUcuscGvbVibGycyHbGycoAbikbikckPcLicLjcLkcwAcLlcLmcLncwAcLocLpcLqckPaabaabbikbikbikbikbikbikbikbikbwocvzbxXbxXbwoaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikafxaabczocHOczqbikczocHOczqaabczocHOczqaabaabaabbikaabbikbikaabaabbikbikbikaabbikbikcJbcKjcKjcKkcLscLscLscLtcLucLvcECcLwcLxcLycLzcLAcLBcLCcLDcLDcLEcLFcLGcGOcGOcGOcLHcLIcLJcLKcLLcLMcLNcLOcLPcECcLQcLQcLRcHhcCAcLScLTcLUcLVcLWcDFcLXcLYcLZcMacMbcCKcCKcCKcCKcCKcHBcoDcEhcLbbGybGybYDclUcNEczVczVcOtcDZcQMcRwcyTdbkcYuclUcuscGvczhbGychCcITcoAbikbikckPcMpcxOcxOcwAcMpcxOcxOcwAcMpcxOcxOckPbikaabaabbikbikbikbikbikbikbikbwocLccyJbxXbwobwobwocJNcJNaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikagiaabczocMqczqbikczocMqczqbikczocMqczqaabafxaabaabaabaabaabaabbikbikbikbikbikbikaabcJbcMrcMscLscLscLscMtcMucMucMucMucMucMucMucMvcMwcMxcMycMzcMzcMzcMAcMBdcpdcodcvcMzcMBcMDcMEcMFcLMcMGcLOcLPcMHcMIcMJcMKcMLcMMcMNcMOcKNcMPcMQcMRcMScMTcMUcIDcMVcDQcMWcMXcMXcCKcHBcoAcEhbVicozcLdbYDclUcOBczVcQgcPYcySdcydczcyTdcBdcAclUcuscGvbVibGybVibVicoAaabaabckPcNncBZcxOcwAcNncBZcxOcwAcNncBZcxOckPbikbikaabaabbikbikbikbikbikbikbwocvzcyJcLecyJcLfbwoaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 9c9b8db5727..212a19f79e8 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -43,11 +43,11 @@ #define HAS_LIPS 64 #define IS_PLANT 128 #define CAN_BE_FAT 256 -#define IS_RESTRICTED 512 -#define NO_INTORGANS 1024 -#define NO_POISON 2048 -#define RADIMMUNE 4096 -#define ALL_RPARTS 8192 +#define NO_INTORGANS 512 +#define NO_POISON 1024 +#define RADIMMUNE 2048 +#define ALL_RPARTS 4096 +#define NOGUNS 8192 //Species clothing flags #define HAS_UNDERWEAR 1 diff --git a/code/__DEFINES/mob.dm b/code/__DEFINES/mob.dm index 8cb7556ab3e..82ca895b42d 100644 --- a/code/__DEFINES/mob.dm +++ b/code/__DEFINES/mob.dm @@ -76,7 +76,11 @@ #define APPEARANCE_FACIAL_HAIR_COLOR 128 #define APPEARANCE_EYE_COLOR 256 #define APPEARANCE_ALL_HAIR APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR -#define APPEARANCE_ALL 511 +#define APPEARANCE_HEAD_ACCESSORY 512 +#define APPEARANCE_MARKINGS 1024 +#define APPEARANCE_BODY_ACCESSORY 2048 +#define APPEARANCE_ALL_BODY APPEARANCE_ALL_HAIR|APPEARANCE_HEAD_ACCESSORY|APPEARANCE_MARKINGS|APPEARANCE_BODY_ACCESSORY +#define APPEARANCE_ALL 4095 // Intents #define I_HELP "help" diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index f8980d61ddd..3d1648fa77a 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -52,7 +52,7 @@ proc/random_hair_style(var/gender, species = "Human") if(valid_hairstyles.len) h_style = pick(valid_hairstyles) - return h_style + return h_style proc/GetOppositeDir(var/dir) switch(dir) diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index 0a891be21f5..233add211f6 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -50,7 +50,8 @@ T.client.screen -= button qdel(button) button = null - T.actions.Remove(src) + if(T.actions) + T.actions.Remove(src) T.update_action_buttons() owner = null return diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 9cf42a511fd..f4e795f6c77 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -68,6 +68,8 @@ var/assistantlimit = 0 //enables assistant limiting var/assistantratio = 2 //how many assistants to security members + var/traitor_objectives_amount = 2 + var/max_maint_drones = 5 //This many drones can spawn, var/allow_drone_spawn = 1 //assuming the admin allow them to. var/drone_build_time = 1200 //A drone will become available every X ticks since last drone spawn. Default is 2 minutes. @@ -598,6 +600,8 @@ config.limbs_can_break = value if("shuttle_refuel_delay") config.shuttle_refuel_delay = text2num(value) + if("traitor_objectives_amount") + config.traitor_objectives_amount = text2num(value) if("reactionary_explosions") config.reactionary_explosions = 1 if("bombcap") diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index a70875a7090..d07b6e3eb73 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -126,6 +126,7 @@ proc/get_id_photo(var/mob/living/carbon/human/H) var/icon/preview_icon = null + var/obj/item/organ/external/head/head_organ = H.get_organ("head") var/g = "m" if (H.gender == FEMALE) @@ -170,32 +171,32 @@ proc/get_id_photo(var/mob/living/carbon/human/H) eyes_s.Blend(rgb(H.r_eyes, H.g_eyes, H.b_eyes), ICON_ADD) face_s.Blend(eyes_s, ICON_OVERLAY) - var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style] + var/datum/sprite_accessory/hair_style = hair_styles_list[head_organ.h_style] if(hair_style) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") // I'll want to make a species-specific proc for this sooner or later // But this'll do for now - if(H.get_species() == "Slime People") + if(head_organ.species.name == "Slime People") hair_s.Blend(rgb(H.r_skin, H.g_skin, H.b_skin, 160), ICON_ADD) else - hair_s.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD) + hair_s.Blend(rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair), ICON_ADD) face_s.Blend(hair_s, ICON_OVERLAY) //Head Accessory - if(H.species.bodyflags & HAS_HEAD_ACCESSORY) - var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[H.ha_style] + if(head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) + var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[head_organ.ha_style] if(head_accessory_style && head_accessory_style.species_allowed) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") - head_accessory_s.Blend(rgb(H.r_headacc, H.g_headacc, H.b_headacc), ICON_ADD) + head_accessory_s.Blend(rgb(head_organ.r_headacc, head_organ.g_headacc, head_organ.b_headacc), ICON_ADD) face_s.Blend(head_accessory_s, ICON_OVERLAY) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style] + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[head_organ.f_style] if(facial_hair_style && facial_hair_style.species_allowed) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(H.get_species() == "Slime People") + if(head_organ.species.name == "Slime People") facial_s.Blend(rgb(H.r_skin, H.g_skin, H.b_skin, 160), ICON_ADD) else - facial_s.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD) + facial_s.Blend(rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial), ICON_ADD) face_s.Blend(facial_s, ICON_OVERLAY) //Markings diff --git a/code/datums/diseases/advance/symptoms/beard.dm b/code/datums/diseases/advance/symptoms/beard.dm index 1dda9b46f7f..2ce411367f8 100644 --- a/code/datums/diseases/advance/symptoms/beard.dm +++ b/code/datums/diseases/advance/symptoms/beard.dm @@ -30,20 +30,21 @@ BONUS var/mob/living/M = A.affected_mob if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M + var/obj/item/organ/external/head/head_organ = H.get_organ("head") switch(A.stage) if(1, 2) to_chat(H, "Your chin itches.") - if(H.f_style == "Shaved") - H.f_style = "Jensen Beard" - H.update_hair() + if(head_organ.f_style == "Shaved") + head_organ.f_style = "Jensen Beard" + H.update_fhair() if(3, 4) to_chat(H, "You feel tough.") - if(!(H.f_style == "Dwarf Beard") && !(H.f_style == "Very Long Beard") && !(H.f_style == "Full Beard")) - H.f_style = "Full Beard" - H.update_hair() + if(!(head_organ.f_style == "Dwarf Beard") && !(head_organ.f_style == "Very Long Beard") && !(head_organ.f_style == "Full Beard")) + head_organ.f_style = "Full Beard" + H.update_fhair() else to_chat(H, "You feel manly!") - if(!(H.f_style == "Dwarf Beard") && !(H.f_style == "Very Long Beard")) - H.f_style = pick("Dwarf Beard", "Very Long Beard") - H.update_hair() + if(!(head_organ.f_style == "Dwarf Beard") && !(head_organ.f_style == "Very Long Beard")) + head_organ.f_style = pick("Dwarf Beard", "Very Long Beard") + H.update_fhair() return \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index b25c4bacf47..99f670c258e 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -31,7 +31,7 @@ Bonus switch(A.stage) if(2) if(M.reagents.get_reagent_amount("oculine")<10) - M.reagents.add_reagent("oculine"=10) + M.reagents.add_reagent("oculine", 10) to_chat(M, "Your hearing feels clearer and crisp.") if(3) if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("oculine") < 10 ) diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm index f7f52984c0b..e79b87d1d4b 100644 --- a/code/datums/diseases/advance/symptoms/shedding.dm +++ b/code/datums/diseases/advance/symptoms/shedding.dm @@ -31,18 +31,20 @@ BONUS to_chat(M, "[pick("Your scalp itches.", "Your skin feels flakey.")]") if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M + var/obj/item/organ/external/head/head_organ = H.get_organ("head") switch(A.stage) if(3, 4) - if(!(H.h_style == "Bald") && !(H.h_style == "Balding Hair")) + if(!(head_organ.h_style == "Bald") && !(head_organ.h_style == "Balding Hair")) to_chat(H, "Your hair starts to fall out in clumps...") spawn(50) - H.h_style = "Balding Hair" + head_organ.h_style = "Balding Hair" H.update_hair() if(5) - if(!(H.f_style == "Shaved") || !(H.h_style == "Bald")) + if(!(head_organ.f_style == "Shaved") || !(head_organ.h_style == "Bald")) to_chat(H, "Your hair starts to fall out in clumps...") spawn(50) - H.f_style = "Shaved" - H.h_style = "Bald" + head_organ.f_style = "Shaved" + head_organ.h_style = "Bald" H.update_hair() + H.update_fhair() return \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index ea478d6b9e0..a3d9dbd8442 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -485,13 +485,13 @@ if(!def_value)//If it's a custom objective, it will be an empty string. def_value = "custom" - var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "blood", "debrain", "protect", "prevent", "harm", "brig", "hijack", "escape", "survive", "steal", "download", "nuclear", "capture", "absorb", "destroy", "maroon", "identity theft", "custom") + var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "blood", "debrain", "protect", "prevent", "brig", "hijack", "escape", "survive", "steal", "download", "nuclear", "capture", "absorb", "destroy", "maroon", "identity theft", "custom") if (!new_obj_type) return var/datum/objective/new_objective = null switch (new_obj_type) - if ("assassinate","protect","debrain", "harm", "brig", "maroon") + if ("assassinate","protect","debrain", "brig", "maroon") //To determine what to name the objective in explanation text. var/objective_type_capital = uppertext(copytext(new_obj_type, 1,2))//Capitalize first letter. var/objective_type_text = copytext(new_obj_type, 2)//Leave the rest of the text. diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index a15170a3956..93d7cc473dc 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -133,19 +133,20 @@ var/global/list/bad_blocks[0] ResetUI(1) // Hair // FIXME: Species-specific defaults pls - if(!character.h_style) - character.h_style = "Skinhead" - var/hair = hair_styles_list.Find(character.h_style) + var/obj/item/organ/external/head/H = character.get_organ("head") + if(!H.h_style) + H.h_style = "Skinhead" + var/hair = hair_styles_list.Find(H.h_style) // Facial Hair - if(!character.f_style) - character.f_style = "Shaved" - var/beard = facial_hair_styles_list.Find(character.f_style) + if(!H.f_style) + H.f_style = "Shaved" + var/beard = facial_hair_styles_list.Find(H.f_style) // Head Accessory - if(!character.ha_style) - character.ha_style = "None" - var/headacc = head_accessory_styles_list.Find(character.ha_style) + if(!H.ha_style) + H.ha_style = "None" + var/headacc = head_accessory_styles_list.Find(H.ha_style) /*// Body Accessory if(!character.body_accessory) @@ -157,13 +158,13 @@ var/global/list/bad_blocks[0] character.m_style = "None" var/marks = marking_styles_list.Find(character.m_style) - SetUIValueRange(DNA_UI_HAIR_R, character.r_hair, 255, 1) - SetUIValueRange(DNA_UI_HAIR_G, character.g_hair, 255, 1) - SetUIValueRange(DNA_UI_HAIR_B, character.b_hair, 255, 1) + SetUIValueRange(DNA_UI_HAIR_R, H.r_hair, 255, 1) + SetUIValueRange(DNA_UI_HAIR_G, H.g_hair, 255, 1) + SetUIValueRange(DNA_UI_HAIR_B, H.b_hair, 255, 1) - SetUIValueRange(DNA_UI_BEARD_R, character.r_facial, 255, 1) - SetUIValueRange(DNA_UI_BEARD_G, character.g_facial, 255, 1) - SetUIValueRange(DNA_UI_BEARD_B, character.b_facial, 255, 1) + SetUIValueRange(DNA_UI_BEARD_R, H.r_facial, 255, 1) + SetUIValueRange(DNA_UI_BEARD_G, H.g_facial, 255, 1) + SetUIValueRange(DNA_UI_BEARD_B, H.b_facial, 255, 1) SetUIValueRange(DNA_UI_EYES_R, character.r_eyes, 255, 1) SetUIValueRange(DNA_UI_EYES_G, character.g_eyes, 255, 1) @@ -173,9 +174,9 @@ var/global/list/bad_blocks[0] SetUIValueRange(DNA_UI_SKIN_G, character.g_skin, 255, 1) SetUIValueRange(DNA_UI_SKIN_B, character.b_skin, 255, 1) - SetUIValueRange(DNA_UI_HACC_R, character.r_headacc, 255, 1) - SetUIValueRange(DNA_UI_HACC_G, character.g_headacc, 255, 1) - SetUIValueRange(DNA_UI_HACC_B, character.b_headacc, 255, 1) + SetUIValueRange(DNA_UI_HACC_R, H.r_headacc, 255, 1) + SetUIValueRange(DNA_UI_HACC_G, H.g_headacc, 255, 1) + SetUIValueRange(DNA_UI_HACC_B, H.b_headacc, 255, 1) SetUIValueRange(DNA_UI_MARK_R, character.r_markings, 255, 1) SetUIValueRange(DNA_UI_MARK_G, character.g_markings, 255, 1) diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 781c3a1d230..53f248d1e91 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -131,13 +131,14 @@ src.dna.UpdateUI() dna.check_integrity() var/mob/living/carbon/human/H = src - H.r_hair = dna.GetUIValueRange(DNA_UI_HAIR_R, 255) - H.g_hair = dna.GetUIValueRange(DNA_UI_HAIR_G, 255) - H.b_hair = dna.GetUIValueRange(DNA_UI_HAIR_B, 255) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + head_organ.r_hair = dna.GetUIValueRange(DNA_UI_HAIR_R, 255) + head_organ.g_hair = dna.GetUIValueRange(DNA_UI_HAIR_G, 255) + head_organ.b_hair = dna.GetUIValueRange(DNA_UI_HAIR_B, 255) - H.r_facial = dna.GetUIValueRange(DNA_UI_BEARD_R, 255) - H.g_facial = dna.GetUIValueRange(DNA_UI_BEARD_G, 255) - H.b_facial = dna.GetUIValueRange(DNA_UI_BEARD_B, 255) + head_organ.r_facial = dna.GetUIValueRange(DNA_UI_BEARD_R, 255) + head_organ.g_facial = dna.GetUIValueRange(DNA_UI_BEARD_G, 255) + head_organ.b_facial = dna.GetUIValueRange(DNA_UI_BEARD_B, 255) H.r_skin = dna.GetUIValueRange(DNA_UI_SKIN_R, 255) H.g_skin = dna.GetUIValueRange(DNA_UI_SKIN_G, 255) @@ -147,9 +148,9 @@ H.g_eyes = dna.GetUIValueRange(DNA_UI_EYES_G, 255) H.b_eyes = dna.GetUIValueRange(DNA_UI_EYES_B, 255) - H.r_headacc = dna.GetUIValueRange(DNA_UI_HACC_R, 255) - H.g_headacc = dna.GetUIValueRange(DNA_UI_HACC_G, 255) - H.b_headacc = dna.GetUIValueRange(DNA_UI_HACC_B, 255) + head_organ.r_headacc = dna.GetUIValueRange(DNA_UI_HACC_R, 255) + head_organ.g_headacc = dna.GetUIValueRange(DNA_UI_HACC_G, 255) + head_organ.b_headacc = dna.GetUIValueRange(DNA_UI_HACC_B, 255) H.r_markings = dna.GetUIValueRange(DNA_UI_MARK_R, 255) H.g_markings = dna.GetUIValueRange(DNA_UI_MARK_G, 255) @@ -168,17 +169,17 @@ //Hair var/hair = dna.GetUIValueRange(DNA_UI_HAIR_STYLE,hair_styles_list.len) if((0 < hair) && (hair <= hair_styles_list.len)) - H.h_style = hair_styles_list[hair] + head_organ.h_style = hair_styles_list[hair] //Facial Hair var/beard = dna.GetUIValueRange(DNA_UI_BEARD_STYLE,facial_hair_styles_list.len) if((0 < beard) && (beard <= facial_hair_styles_list.len)) - H.f_style = facial_hair_styles_list[beard] + head_organ.f_style = facial_hair_styles_list[beard] //Head Accessories var/headacc = dna.GetUIValueRange(DNA_UI_HACC_STYLE,head_accessory_styles_list.len) if((0 < headacc) && (headacc <= head_accessory_styles_list.len)) - H.ha_style = head_accessory_styles_list[headacc] + head_organ.ha_style = head_accessory_styles_list[headacc] //Markings var/marks = dna.GetUIValueRange(DNA_UI_MARK_STYLE,marking_styles_list.len) diff --git a/code/game/dna/genes/powers.dm b/code/game/dna/genes/powers.dm index 2aca5878f83..eb33cef7ccf 100644 --- a/code/game/dna/genes/powers.dm +++ b/code/game/dna/genes/powers.dm @@ -144,8 +144,8 @@ /datum/dna/gene/basic/tk name="Telekenesis" - activation_messages=list("You feel smarter.") - deactivation_messages=("You feel dumber.") + activation_messages = list("You feel smarter.") + deactivation_messages = list("You feel dumber.") mutation=TK activation_prob=10 diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index 8a854c7980d..13f334c010b 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -37,61 +37,7 @@ to_chat(usr, "\red You can't change your appearance right now!") return var/mob/living/carbon/human/M=usr - - var/new_facial = input("Please select facial hair color.", "Character Generation",rgb(M.r_facial,M.g_facial,M.b_facial)) as null|color - if(new_facial) - M.r_facial = hex2num(copytext(new_facial, 2, 4)) - M.g_facial = hex2num(copytext(new_facial, 4, 6)) - M.b_facial = hex2num(copytext(new_facial, 6, 8)) - - var/new_hair = input("Please select hair color.", "Character Generation",rgb(M.r_hair,M.g_hair,M.b_hair)) as null|color - if(new_facial) - M.r_hair = hex2num(copytext(new_hair, 2, 4)) - M.g_hair = hex2num(copytext(new_hair, 4, 6)) - M.b_hair = hex2num(copytext(new_hair, 6, 8)) - - var/new_eyes = input("Please select eye color.", "Character Generation",rgb(M.r_eyes,M.g_eyes,M.b_eyes)) as null|color - if(new_eyes) - M.r_eyes = hex2num(copytext(new_eyes, 2, 4)) - M.g_eyes = hex2num(copytext(new_eyes, 4, 6)) - M.b_eyes = hex2num(copytext(new_eyes, 6, 8)) - - var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[35-M.s_tone]") as null|text - - if (!new_tone) - new_tone = 35 - M.s_tone = max(min(round(text2num(new_tone)), 220), 1) - M.s_tone = -M.s_tone + 35 - - // hair - var/list/all_hairs = subtypesof(/datum/sprite_accessory/hair) - var/list/hairs = list() - - // loop through potential hairs - for(var/x in all_hairs) - var/datum/sprite_accessory/hair/H = new x // create new hair datum based on type x - hairs.Add(H.name) // add hair name to hairs - qdel(H) // delete the hair after it's all done - - var/new_style = input("Please select hair style", "Character Generation",M.h_style) as null|anything in hairs - - // if new style selected (not cancel) - if (new_style) - M.h_style = new_style - - // facial hair - var/list/all_fhairs = subtypesof(/datum/sprite_accessory/facial_hair) - var/list/fhairs = list() - - for(var/x in all_fhairs) - var/datum/sprite_accessory/facial_hair/H = new x - fhairs.Add(H.name) - qdel(H) - - new_style = input("Please select facial style", "Character Generation",M.f_style) as null|anything in fhairs - - if(new_style) - M.f_style = new_style + var/obj/item/organ/external/head/head_organ = M.get_organ("head") var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female") if (new_gender) @@ -99,8 +45,93 @@ M.change_gender(MALE) else M.change_gender(FEMALE) + + var/new_eyes = input("Please select eye color.", "Character Generation", rgb(M.r_eyes,M.g_eyes,M.b_eyes)) as null|color + if(new_eyes) + M.r_eyes = hex2num(copytext(new_eyes, 2, 4)) + M.g_eyes = hex2num(copytext(new_eyes, 4, 6)) + M.b_eyes = hex2num(copytext(new_eyes, 6, 8)) + M.change_eye_color(M.r_eyes, M.g_eyes, M.b_eyes) + + // hair + var/list/valid_hairstyles = M.generate_valid_hairstyles() + var/new_style = input("Please select hair style", "Character Generation", head_organ.h_style) as null|anything in valid_hairstyles + + // if new style selected (not cancel) + if (new_style) + head_organ.h_style = new_style + + var/new_hair = input("Please select hair color.", "Character Generation", rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair)) as null|color + if(new_hair) + head_organ.r_hair = hex2num(copytext(new_hair, 2, 4)) + head_organ.g_hair = hex2num(copytext(new_hair, 4, 6)) + head_organ.b_hair = hex2num(copytext(new_hair, 6, 8)) + + // facial hair + var/list/valid_facial_hairstyles = M.generate_valid_facial_hairstyles() + new_style = input("Please select facial style", "Character Generation", head_organ.f_style) as null|anything in valid_facial_hairstyles + + if(new_style) + head_organ.f_style = new_style + + var/new_facial = input("Please select facial hair color.", "Character Generation", rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial)) as null|color + if(new_facial) + head_organ.r_facial = hex2num(copytext(new_facial, 2, 4)) + head_organ.g_facial = hex2num(copytext(new_facial, 4, 6)) + head_organ.b_facial = hex2num(copytext(new_facial, 6, 8)) + + //Head accessory. + if(head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) + var/list/valid_head_accessories = M.generate_valid_head_accessories() + var/new_head_accessory = input("Please select head accessory style", "Character Generation", head_organ.ha_style) as null|anything in valid_head_accessories + if(new_head_accessory) + head_organ.ha_style = new_head_accessory + + var/new_head_accessory_colour = input("Please select head accessory colour.", "Character Generation", rgb(head_organ.r_headacc, head_organ.g_headacc, head_organ.b_headacc)) as null|color + if(new_head_accessory_colour) + head_organ.r_headacc = hex2num(copytext(new_head_accessory_colour, 2, 4)) + head_organ.g_headacc = hex2num(copytext(new_head_accessory_colour, 4, 6)) + head_organ.b_headacc = hex2num(copytext(new_head_accessory_colour, 6, 8)) + + //Body markings. + if(M.species.bodyflags & HAS_MARKINGS) + var/list/valid_markings = M.generate_valid_markings() + var/new_marking = input("Please select marking style", "Character Generation", M.m_style) as null|anything in valid_markings + if(new_marking) + M.m_style = new_marking + + var/new_marking_colour = input("Please select marking colour.", "Character Generation", rgb(M.r_markings, M.g_markings, M.b_markings)) as null|color + if(new_marking_colour) + M.r_markings = hex2num(copytext(new_marking_colour, 2, 4)) + M.g_markings = hex2num(copytext(new_marking_colour, 4, 6)) + M.b_markings = hex2num(copytext(new_marking_colour, 6, 8)) + + //Body accessory. + if(M.species.tail && M.species.bodyflags & HAS_TAIL) + var/list/valid_body_accessories = M.generate_valid_body_accessories() + if(valid_body_accessories.len > 1) //By default valid_body_accessories will always have at the very least a 'none' entry populating the list, even if the user's species is not present in any of the list items. + var/new_body_accessory = input("Please select body accessory style", "Character Generation", M.body_accessory) as null|anything in valid_body_accessories + if(new_body_accessory) + M.body_accessory = body_accessory_by_name[new_body_accessory] + + //Skin tone. + if(M.species.bodyflags & HAS_SKIN_TONE) + var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[M.s_tone]") as null|text + if (!new_tone) + new_tone = 35 + M.s_tone = 35 - max(min(round(text2num(new_tone)), 220), 1) + + //Skin colour. + if(M.species.bodyflags & HAS_SKIN_COLOR) + var/new_body_colour = input("Please select body colour.", "Character Generation", rgb(M.r_skin, M.g_skin, M.b_skin)) as null|color + if(new_body_colour) + M.r_skin = hex2num(copytext(new_body_colour, 2, 4)) + M.g_skin = hex2num(copytext(new_body_colour, 4, 6)) + M.b_skin = hex2num(copytext(new_body_colour, 6, 8)) + + M.force_update_limbs() M.regenerate_icons() - M.check_dna() + M.update_dna() M.visible_message("\blue \The [src] morphs and changes [M.get_visible_gender() == MALE ? "his" : M.get_visible_gender() == FEMALE ? "her" : "their"] appearance!", "\blue You change your appearance!", "\red Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!") diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index a35505470fa..229b35660a3 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -68,6 +68,7 @@ ..() /mob/living/simple_animal/hostile/blob/blobspore/proc/Zombify(var/mob/living/carbon/human/H) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") is_zombie = 1 if(H.wear_suit) var/obj/item/clothing/suit/armor/A = H.wear_suit @@ -82,7 +83,7 @@ icon = H.icon speak_emote = list("groans") icon_state = "zombie2_s" - H.h_style = null + head_organ.h_style = null H.update_hair() human_overlays = H.overlays update_icons() diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 28ebdeae677..952b43d5f37 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -94,6 +94,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah")) var/mob/living/carbon/human/vox = newraider.current + var/obj/item/organ/external/head/head_organ = vox.get_organ("head") vox.real_name = capitalize(newname) vox.name = vox.real_name @@ -105,8 +106,8 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' vox.add_language("Vox-pidgin") vox.add_language("Galactic Common") vox.add_language("Tradeband") - vox.h_style = "Short Vox Quills" - vox.f_style = "Shaved" + head_organ.h_style = "Short Vox Quills" + head_organ.f_style = "Shaved" for(var/obj/item/organ/external/limb in vox.organs) limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT) diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index 9e25a50a811..1a0d7770a1a 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -80,6 +80,7 @@ density = 0 pass_flags = PASSTABLE ventcrawler = 2 + 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) var/talk_inside_host = 0 // So that borers don't accidentally give themselves away on a botched message var/used_dominate diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index e10dce617fa..0268133a5d1 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -133,6 +133,8 @@ proc/issyndicate(mob/living/M as mob) /datum/game_mode/proc/create_syndicate(var/datum/mind/synd_mind) // So we don't have inferior species as ops - randomize a human var/mob/living/carbon/human/M = synd_mind.current + var/obj/item/organ/external/head/head_organ = M.get_organ("head") + M.set_species("Human",1) M.dna.ready_dna(M) // Quadriplegic Nuke Ops won't be participating in the paralympics @@ -149,18 +151,18 @@ proc/issyndicate(mob/living/M as mob) if(prob(5)) facial_hair_style = pick(facial_hair_styles_list) - M.r_facial = hex2num(copytext(hair_c, 2, 4)) - M.g_facial = hex2num(copytext(hair_c, 4, 6)) - M.b_facial = hex2num(copytext(hair_c, 6, 8)) - M.r_hair = hex2num(copytext(hair_c, 2, 4)) - M.g_hair = hex2num(copytext(hair_c, 4, 6)) - M.b_hair = hex2num(copytext(hair_c, 6, 8)) + head_organ.r_facial = hex2num(copytext(hair_c, 2, 4)) + head_organ.g_facial = hex2num(copytext(hair_c, 4, 6)) + head_organ.b_facial = hex2num(copytext(hair_c, 6, 8)) + head_organ.r_hair = hex2num(copytext(hair_c, 2, 4)) + head_organ.g_hair = hex2num(copytext(hair_c, 4, 6)) + head_organ.b_hair = hex2num(copytext(hair_c, 6, 8)) M.r_eyes = hex2num(copytext(eye_c, 2, 4)) M.g_eyes = hex2num(copytext(eye_c, 4, 6)) M.b_eyes = hex2num(copytext(eye_c, 6, 8)) M.s_tone = skin_tone - M.h_style = hair_style - M.f_style = facial_hair_style + head_organ.h_style = hair_style + head_organ.f_style = facial_hair_style M.body_accessory = null /datum/game_mode/proc/prepare_syndicate_leader(var/datum/mind/synd_mind, var/nuke_code) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 9544d54560c..25b3727ec3a 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -8,12 +8,13 @@ var/list/potential_theft_objectives=subtypesof(/datum/theft_objective) \ - /datum/theft_objective/number/special \ - /datum/theft_objective/number/coins -datum/objective +/datum/objective var/datum/mind/owner = null //Who owns the objective. var/explanation_text = "Nothing" //What that person is supposed to do. var/datum/mind/target = null //If they are focused on a particular person. var/target_amount = 0 //If they are focused on a particular number. Steal objectives have their own counter. var/completed = 0 //currently only used for custom objectives. + var/martyr_compatible = 0 //If the objective is compatible with martyr objective, i.e. if you can still do it while dead. New(var/text) all_objectives |= src @@ -53,7 +54,9 @@ datum/objective target = pick(possible_targets) -datum/objective/assassinate +/datum/objective/assassinate + martyr_compatible = 1 + find_target() ..() if(target && target.current) @@ -81,7 +84,9 @@ datum/objective/assassinate -datum/objective/mutiny +/datum/objective/mutiny + martyr_compatible = 1 + find_target() ..() if(target && target.current) @@ -109,7 +114,7 @@ datum/objective/mutiny return 0 return 1 -datum/objective/mutiny/rp +/datum/objective/mutiny/rp find_target() ..() if(target && target.current) @@ -144,97 +149,9 @@ datum/objective/mutiny/rp return 0 return rval -datum/objective/anti_revolution/execute - find_target() - ..() - if(target && target.current) - explanation_text = "[target.current.real_name], the [target.assigned_role] has extracted confidential information above their clearance. Execute \him[target.current]." - else - explanation_text = "Free Objective" - return target +/datum/objective/maroon + martyr_compatible = 1 - - find_target_by_role(role, role_type=0) - ..(role, role_type) - if(target && target.current) - explanation_text = "[target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] has extracted confidential information above their clearance. Execute \him[target.current]." - else - explanation_text = "Free Objective" - return target - - check_completion() - if(target && target.current) - if(target.current.stat == DEAD || !ishuman(target.current)) - return 1 - return 0 - return 1 - -datum/objective/anti_revolution/brig - var/already_completed = 0 - - find_target() - ..() - if(target && target.current) - explanation_text = "Brig [target.current.real_name], the [target.assigned_role] for 20 minutes to set an example." - else - explanation_text = "Free Objective" - return target - - - find_target_by_role(role, role_type=0) - ..(role, role_type) - if(target && target.current) - explanation_text = "Brig [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] for 20 minutes to set an example." - else - explanation_text = "Free Objective" - return target - - check_completion() - if(already_completed) - return 1 - - if(target && target.current) - if(target.current.stat == DEAD) - return 0 - if(target.is_brigged(10 * 60 * 10)) - already_completed = 1 - return 1 - return 0 - return 0 - -datum/objective/anti_revolution/demote - find_target() - ..() - if(target && target.current) - explanation_text = "[target.current.real_name], the [target.assigned_role] has been classified as harmful to Nanotrasen's goals. Demote \him[target.current] to assistant." - else - explanation_text = "Free Objective" - return target - - find_target_by_role(role, role_type=0) - ..(role, role_type) - if(target && target.current) - explanation_text = "[target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] has been classified as harmful to Nanotrasen's goals. Demote \him[target.current] to assistant." - else - explanation_text = "Free Objective" - return target - - check_completion() - if(target && target.current && istype(target,/mob/living/carbon/human)) - var/obj/item/weapon/card/id/I = target.current:wear_id - if(istype(I, /obj/item/device/pda)) - var/obj/item/device/pda/P = I - I = P.id - - if(!istype(I)) return 1 - - if(I.assignment == "Civilian") - return 1 - else - return 0 - return 1 - -datum/objective/maroon find_target() ..() if(target && target.current) @@ -259,7 +176,9 @@ datum/objective/maroon return 0 return 1 -datum/objective/debrain//I want braaaainssss +/datum/objective/debrain //I want braaaainssss + martyr_compatible = 0 + find_target() ..() if(target && target.current) @@ -292,7 +211,9 @@ datum/objective/debrain//I want braaaainssss return 0 -datum/objective/protect//The opposite of killing a dude. +/datum/objective/protect //The opposite of killing a dude. + martyr_compatible = 1 + find_target() ..() if(target && target.current) @@ -327,7 +248,8 @@ datum/objective/protect//The opposite of killing a dude. return 0 -datum/objective/hijack +/datum/objective/hijack + martyr_compatible = 0 //Technically you won't get both anyway. explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive." check_completion() @@ -358,6 +280,7 @@ datum/objective/hijack /datum/objective/hijackclone explanation_text = "Hijack the emergency shuttle by ensuring only you (or your copies) escape." + martyr_compatible = 0 check_completion() if(!owner.current) @@ -386,8 +309,9 @@ datum/objective/hijack return 1 return 0 -datum/objective/block +/datum/objective/block explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive." + martyr_compatible = 1 check_completion() if(!istype(owner.current, /mob/living/silicon)) @@ -410,9 +334,7 @@ datum/objective/block return 1 - - -datum/objective/escape +/datum/objective/escape explanation_text = "Escape on the shuttle or an escape pod alive and free." var/escape_areas = list(/area/shuttle/escape, /area/shuttle/escape_pod1/centcom, @@ -447,7 +369,7 @@ datum/objective/escape return 0 -datum/objective/escape/escape_with_identity +/datum/objective/escape/escape_with_identity var/target_real_name // Has to be stored because the target's real_name can change over the course of the round find_target() @@ -477,7 +399,7 @@ datum/objective/escape/escape_with_identity return 1 return 0 -datum/objective/die +/datum/objective/die explanation_text = "Die a glorious death." check_completion() @@ -489,7 +411,7 @@ datum/objective/die -datum/objective/survive +/datum/objective/survive explanation_text = "Stay alive until the end." check_completion() @@ -499,98 +421,15 @@ datum/objective/survive return 0 return 1 -// Similar to the anti-rev objective, but for traitors -datum/objective/brig - var/already_completed = 0 - - find_target() - ..() - if(target && target.current) - explanation_text = "Have [target.current.real_name], the [target.assigned_role] brigged for 10 minutes." - else - explanation_text = "Free Objective" - return target - - - find_target_by_role(role, role_type=0) - ..(role, role_type) - if(target && target.current) - explanation_text = "Have [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] brigged for 10 minutes." - else - explanation_text = "Free Objective" - return target - - check_completion() - if(already_completed) - return 1 - - if(target && target.current) - if(target.current.stat == DEAD) - return 0 - // Make the actual required time a bit shorter than the official time - if(target.is_brigged(10 * 60 * 5)) - already_completed = 1 - return 1 - return 0 - return 0 - -// Harm a crew member, making an example of them -datum/objective/harm - var/already_completed = 0 - - find_target() - ..() - if(target && target.current) - explanation_text = "Make an example of [target.current.real_name], the [target.assigned_role]. Break one of their bones, detach one of their limbs or disfigure their face. Make sure they're alive when you do it." - else - explanation_text = "Free Objective" - return target - - - find_target_by_role(role, role_type=0) - ..(role, role_type) - if(target && target.current) - explanation_text = "Make an example of [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]. Break one of their bones, detach one of their limbs or disfigure their face. Make sure they're alive when you do it." - else - explanation_text = "Free Objective" - return target - - check_completion() - if(already_completed) - return 1 - - if(target && target.current && istype(target.current, /mob/living/carbon/human)) - if(target.current.stat == DEAD) - return 0 - - var/mob/living/carbon/human/H = target.current - for(var/obj/item/organ/external/E in H.organs) - if(E.status & ORGAN_BROKEN) - return 1 - for(var/limb_tag in H.species.has_limbs) //todo check prefs for robotic limbs and amputations. - var/list/organ_data = H.species.has_limbs[limb_tag] - var/limb_type = organ_data["path"] - var/found - for(var/obj/item/organ/external/E in H.organs) - if(limb_type == E.type) - found = 1 - break - if(!found) - return 1 - - var/obj/item/organ/external/head/head = H.get_organ("head") - if(head.disfigured) - return 1 - return 0 - - -datum/objective/nuclear +/datum/objective/nuclear explanation_text = "Destroy the station with a nuclear device." + martyr_compatible = 1 -datum/objective/steal +/datum/objective/steal var/datum/theft_objective/steal_target + martyr_compatible = 0 find_target(var/special_only=0) var/loop=50 @@ -638,7 +477,8 @@ datum/objective/steal if(!steal_target) return 1 // Free Objective return steal_target.check_completion(owner) -datum/objective/steal/exchange +/datum/objective/steal/exchange + martyr_compatible = 0 proc/set_faction(var/faction,var/otheragent) target = otheragent @@ -650,7 +490,7 @@ datum/objective/steal/exchange explanation_text = "Acquire [targetinfo.name] held by [target.current.real_name], the [target.assigned_role] and syndicate agent" steal_target = targetinfo -datum/objective/steal/exchange/backstab +/datum/objective/steal/exchange/backstab set_faction(var/faction) var/datum/theft_objective/unique/targetinfo @@ -661,7 +501,7 @@ datum/objective/steal/exchange/backstab explanation_text = "Do not give up or lose [targetinfo.name]." steal_target = targetinfo -datum/objective/download +/datum/objective/download proc/gen_amount_goal() target_amount = rand(10,20) explanation_text = "Download [target_amount] research levels." @@ -673,7 +513,7 @@ datum/objective/download -datum/objective/capture +/datum/objective/capture proc/gen_amount_goal() target_amount = rand(5,10) explanation_text = "Accumulate [target_amount] capture points." @@ -686,7 +526,7 @@ datum/objective/capture -datum/objective/absorb +/datum/objective/absorb proc/gen_amount_goal(var/lowbound = 4, var/highbound = 6) target_amount = rand (lowbound,highbound) if (ticker) @@ -714,8 +554,10 @@ datum/objective/absorb else return 0 -datum/objective/destroy +/datum/objective/destroy + martyr_compatible = 1 var/target_real_name + find_target() var/list/possible_targets = active_ais(1) var/mob/living/silicon/ai/target_ai = pick(possible_targets) @@ -734,71 +576,7 @@ datum/objective/destroy return 0 return 1 -/* Isn't suited for global objectives -/*---------CULTIST----------*/ - - eldergod - explanation_text = "Summon Nar-Sie via the use of an appropriate rune. It will only work if nine cultists stand on and around it." - - check_completion() - if(!eldergod) //global var, defined in rune4.dm - return 1 - return 0 - - survivecult - var/num_cult - var/cult_needed = 4 + round((num_players_started() / 10)) - - explanation_text = "Our knowledge must live on. Make sure at least [cult_needed] acolytes escape on the shuttle to spread their work on an another station." - - check_completion() - if(!emergency_shuttle.returned()) - return 0 - - var/cultists_escaped = 0 - - var/area/shuttle/escape/centcom/C = /area/shuttle/escape/centcom - for(var/turf/T in get_area_turfs(C.type)) - for(var/mob/living/carbon/H in T) - if(iscultist(H)) - cultists_escaped++ - - if(cultists_escaped >= cult_needed) - return 1 - - return 0 - - sacrifice //stolen from traitor target objective - - proc/find_target() //I don't know how to make it work with the rune otherwise, so I'll do it via a global var, sacrifice_target, defined in rune15.dm - var/datum/game_mode/cult/C = ticker.mode - var/list/possible_targets = C.get_unconvertables() - - if(!possible_targets.len) - for(var/mob/living/carbon/human/player in player_list) - if(player.mind && !(player.mind in cult)) - possible_targets += player.mind - - if(possible_targets.len > 0) - sacrifice_target = pick(possible_targets) - - if(sacrifice_target && sacrifice_target.current) - explanation_text = "Sacrifice [sacrifice_target.current.real_name], the [sacrifice_target.assigned_role]. You will need the sacrifice rune (hell join blood) and three acolytes to do so." - else - explanation_text = "Free Objective" - - return sacrifice_target - - check_completion() //again, calling on a global list defined in rune15.dm - if(sacrifice_target in sacrificed) - return 1 - else - return 0 - -/*-------ENDOF CULTIST------*/ -*/ - -datum/objective/blood +/datum/objective/blood proc/gen_amount_goal(low = 150, high = 400) target_amount = rand(low,high) target_amount = round(round(target_amount/5)*5) @@ -812,7 +590,7 @@ datum/objective/blood return 0 // /vg/; Vox Inviolate for humans :V -datum/objective/minimize_casualties +/datum/objective/minimize_casualties explanation_text = "Minimise casualties." check_completion() if(owner.kills.len>5) return 0 @@ -820,11 +598,11 @@ datum/objective/minimize_casualties //Vox heist objectives. -datum/objective/heist +/datum/objective/heist proc/choose_target() return -datum/objective/heist/kidnap +/datum/objective/heist/kidnap choose_target() var/list/roles = list("Chief Engineer","Research Director","Roboticist","Chemist","Station Engineer") var/list/possible_targets = list() @@ -866,7 +644,7 @@ datum/objective/heist/kidnap else return 0 -datum/objective/heist/loot +/datum/objective/heist/loot choose_target() var/loot = "an object" switch(rand(1,8)) @@ -937,7 +715,7 @@ datum/objective/heist/loot return 0 -datum/objective/heist/salvage +/datum/objective/heist/salvage choose_target() switch(rand(1,8)) if(1) @@ -1009,7 +787,7 @@ datum/objective/heist/salvage return 0 -datum/objective/heist/inviolate_crew +/datum/objective/heist/inviolate_crew explanation_text = "Do not leave any Vox behind, alive or dead." check_completion() @@ -1022,7 +800,7 @@ datum/objective/heist/inviolate_crew //Would be nice to use vox-specific kills but is currently not feasible. var/global/vox_kills = 0 //Used to check the Inviolate. -datum/objective/heist/inviolate_death +/datum/objective/heist/inviolate_death explanation_text = "Follow the Inviolate. Minimise death and loss of resources." check_completion() if(vox_kills > MAX_VOX_KILLS) return 0 diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 7c8100edbc5..24129a6d49f 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -301,7 +301,7 @@ Made by Xhuis blood_color = "#555555" flesh_color = "#222222" - flags = NO_BLOOD | NO_BREATHE | RADIMMUNE + flags = NO_BLOOD | NO_BREATHE | RADIMMUNE | NOGUNS //Can't use guns due to muzzle flash burn_mod = 1.5 //1.5x burn damage, 2x is excessive hot_env_multiplier = 1.5 diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index c0d0edf89e3..c7fcd59dfe4 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -74,101 +74,107 @@ ..() -/datum/game_mode/proc/forge_traitor_objectives(var/datum/mind/traitor) +/datum/game_mode/proc/forge_traitor_objectives(datum/mind/traitor) if(istype(traitor.current, /mob/living/silicon)) - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = traitor - kill_objective.find_target() - traitor.objectives += kill_objective + 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() + 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 var/datum/objective/survive/survive_objective = new survive_objective.owner = traitor traitor.objectives += survive_objective - if(prob(10)) - var/datum/objective/block/block_objective = new - block_objective.owner = traitor - traitor.objectives += block_objective - else - if(!exchange_blue && traitors.len >= 5 && name != "AutoTraitor") //Set up an exchange if there are enough traitors, turned off during autotraitor temporarily due to bugs. + 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) - else - var/list/active_ais = active_ais() - if(active_ais.len && prob(4)) // Leaving this at a flat chance for now, problems with the num_players() proc due to latejoin antags. - var/datum/objective/destroy/destroy_objective = new - destroy_objective.owner = traitor - destroy_objective.find_target() - traitor.objectives += destroy_objective - else - switch(rand(1,100)) - if(1 to 30) - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = traitor - kill_objective.find_target() - traitor.objectives += kill_objective - if(31 to 40) - var/datum/objective/debrain/debrain_objective = new - debrain_objective.owner = traitor - debrain_objective.find_target() - traitor.objectives += debrain_objective - if(41 to 50) - var/datum/objective/protect/protect_objective = new - protect_objective.owner = traitor - protect_objective.find_target_with_special_role(null,0) - if (!protect_objective.target) - protect_objective.find_target() //We could not find any traitors, protect somebody - traitor.objectives += protect_objective - if(51 to 61) - var/datum/objective/harm/harm_objective = new - harm_objective.owner = traitor - harm_objective.find_target() - traitor.objectives += harm_objective - else - var/datum/objective/steal/steal_objective = new - steal_objective.owner = traitor - steal_objective.find_target() - traitor.objectives += steal_objective - switch(rand(1,100)) - if(1 to 30) // Die glorious death - if (!(locate(/datum/objective/die) in traitor.objectives) && !(locate(/datum/objective/steal) in traitor.objectives) && !(locate(/datum/objective/steal/exchange) in traitor.objectives) && !(locate(/datum/objective/steal/exchange/backstab) in traitor.objectives)) - var/datum/objective/die/die_objective = new - die_objective.owner = traitor - traitor.objectives += die_objective + objective_count += 1 //Exchange counts towards number of objectives + 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/player_list.len)) + var/datum/objective/destroy/destroy_objective = new + destroy_objective.owner = traitor + destroy_objective.find_target() + traitor.objectives += destroy_objective + else if(prob(5)) + var/datum/objective/debrain/debrain_objective = new + debrain_objective.owner = traitor + debrain_objective.find_target() + traitor.objectives += debrain_objective + else if(prob(30)) + var/datum/objective/maroon/maroon_objective = new + maroon_objective.owner = traitor + maroon_objective.find_target() + traitor.objectives += maroon_objective else - if(prob(85)) - if (!(locate(/datum/objective/escape) in traitor.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = traitor - traitor.objectives += escape_objective - else - if(prob(50)) - if (!(locate(/datum/objective/hijack) in traitor.objectives)) - var/datum/objective/hijack/hijack_objective = new - hijack_objective.owner = traitor - traitor.objectives += hijack_objective - else - if (!(locate(/datum/objective/minimize_casualties) in traitor.objectives)) - var/datum/objective/minimize_casualties/escape_objective = new - escape_objective.owner = traitor - traitor.objectives += escape_objective - if(31 to 85) - if (!(locate(/datum/objective/escape) in traitor.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = traitor - traitor.objectives += escape_objective + var/datum/objective/assassinate/kill_objective = new + kill_objective.owner = traitor + kill_objective.find_target() + traitor.objectives += kill_objective else - if (!(locate(/datum/objective/hijack) in traitor.objectives)) - var/datum/objective/hijack/hijack_objective = new - hijack_objective.owner = traitor - traitor.objectives += hijack_objective + var/datum/objective/steal/steal_objective = new + steal_objective.owner = traitor + steal_objective.find_target() + traitor.objectives += steal_objective - return + 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) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 26d159e959a..c131c55ee49 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -799,6 +799,7 @@ About the new airlock wires panel: else return else if(istype(C, /obj/item/weapon/screwdriver)) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 25, 1) src.p_open = !( src.p_open ) src.update_icon() else if(istype(C, /obj/item/weapon/wirecutters)) @@ -1066,4 +1067,4 @@ About the new airlock wires panel: src.unlock() src.open() src.lock() - return \ No newline at end of file + return diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index 15b8b621b0c..5d6aa95b56f 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -621,7 +621,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept //#### Sending the signal to all subspace receivers ####// for(var/obj/machinery/telecomms/receiver/R in telecomms_list) - R.receive_signal(signal) + spawn(0) + R.receive_signal(signal) if(do_sleep) sleep(rand(10,25)) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 744edcd7711..d73edde1525 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -916,6 +916,8 @@ steam.start() -- spawns the effect /obj/effect/effect/foam/New(loc, var/ismetal=0) ..(loc) icon_state = "[ismetal ? "m":""]foam" + if(!ismetal && reagents) + color = mix_color_from_reagents(reagents.reagent_list) metal = ismetal playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3) spawn(3 + metal*3) @@ -944,10 +946,13 @@ steam.start() -- spawns the effect // on delete, transfer any reagents to the floor /obj/effect/effect/foam/Destroy() if(!metal && reagents) - for(var/atom/A in oview(0,src)) + reagents.handle_reactions() + for(var/atom/A in oview(1, src)) if(A == src) continue - reagents.reaction(A, 1, 1) + if(reagents.total_volume) + var/fraction = 5 / reagents.total_volume + reagents.reaction(A, TOUCH, fraction) return ..() /obj/effect/effect/foam/process() @@ -969,13 +974,14 @@ steam.start() -- spawns the effect if(F) continue - F = new(T, metal) + F = new /obj/effect/effect/foam(T, metal) F.amount = amount if(!metal) - F.create_reagents(10) - if (reagents) + F.create_reagents(15) + if(reagents) for(var/datum/reagent/R in reagents.reagent_list) - F.reagents.add_reagent(R.id,1) + F.reagents.add_reagent(R.id, min(R.volume, 3), R.data, reagents.chem_temp) + F.color = mix_color_from_reagents(reagents.reagent_list) // foam disolves when heated // except metal foams @@ -993,16 +999,26 @@ steam.start() -- spawns the effect if (istype(AM, /mob/living/carbon)) var/mob/living/carbon/M = AM - M.slip("foam", 5, 2) + if(M.slip("foam", 5, 2)) + if(reagents) + for(var/reagent_id in reagents.reagent_list) + var/amount = M.reagents.get_reagent_amount(reagent_id) + if(amount < 25) + M.reagents.add_reagent(reagent_id, min(round(amount / 2), 15)) + if(reagents.total_volume) + var/fraction = 5 / reagents.total_volume + reagents.reaction(M, TOUCH, fraction) /datum/effect/system/foam_spread var/amount = 5 // the size of the foam spread. var/list/carried_reagents // the IDs of reagents present when the foam was mixed var/metal = 0 // 0=foam, 1=metalfoam, 2=ironfoam + var/temperature = T0C + var/list/banned_reagents = list("smoke_powder", "fluorosurfactant", "stimulants") /datum/effect/system/foam_spread/set_up(amt=5, loca, var/datum/reagents/carry = null, var/metalfoam = 0) - amount = round(sqrt(amt / 3), 1) + amount = min(round(amt/5, 1), 7) if(istype(loca, /turf/)) location = loca else @@ -1010,35 +1026,40 @@ steam.start() -- spawns the effect carried_reagents = list() metal = metalfoam - + temperature = carry.chem_temp // bit of a hack here. Foam carries along any reagent also present in the glass it is mixed // with (defaults to water if none is present). Rather than actually transfer the reagents, // this makes a list of the reagent ids and spawns 1 unit of that reagent when the foam disolves. - if(carry && !metal) for(var/datum/reagent/R in carry.reagent_list) - carried_reagents += R.id + carried_reagents[R.id] = R.volume /datum/effect/system/foam_spread/start() spawn(0) var/obj/effect/effect/foam/F = locate() in location if(F) F.amount += amount + F.amount = min(F.amount, 27) return - F = new(src.location, metal) + F = new /obj/effect/effect/foam(location, metal) F.amount = amount if(!metal) // don't carry other chemicals if a metal foam - F.create_reagents(10) + F.create_reagents(15) if(carried_reagents) for(var/id in carried_reagents) - F.reagents.add_reagent(id,1) + if(banned_reagents.Find("[id]")) + continue + var/datum/reagent/reagent_volume = carried_reagents[id] + F.reagents.add_reagent(id, min(reagent_volume, 3), null, temperature) + F.color = mix_color_from_reagents(F.reagents.reagent_list) else - F.reagents.add_reagent("water", 1) + F.reagents.add_reagent("cleaner", 1) + F.color = mix_color_from_reagents(F.reagents.reagent_list) // wall formed by metal foams // dense and opaque, but easy to break diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 48e477cc258..ba49f4a9e4c 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -77,6 +77,11 @@ if (!user.IsAdvancedToolUser()) to_chat(user, "You don't have the dexterity to do this!") return + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if((HULK in H.mutations) || (H.species.flags & NOGUNS)) + user << "Your fingers can't press the button!" + return add_fingerprint(user) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 741ecfa7fa2..1f86a35c497 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -422,11 +422,13 @@ var/global/list/default_medbay_channels = list( //#### Sending the signal to all subspace receivers ####// for(var/obj/machinery/telecomms/receiver/R in telecomms_list) - R.receive_signal(signal) + spawn(0) + R.receive_signal(signal) // Allinone can act as receivers. for(var/obj/machinery/telecomms/allinone/R in telecomms_list) - R.receive_signal(signal) + spawn(0) + R.receive_signal(signal) // Receiving code can be located in Telecommunications.dm return signal.data["done"] && position.z in signal.data["level"] @@ -475,7 +477,8 @@ var/global/list/default_medbay_channels = list( signal.frequency = connection.frequency // Quick frequency set for(var/obj/machinery/telecomms/receiver/R in telecomms_list) - R.receive_signal(signal) + spawn(0) + R.receive_signal(signal) sleep(rand(10,25)) // wait a little... @@ -520,7 +523,7 @@ var/global/list/default_medbay_channels = list( // what the range is in which mobs will hear the radio // returns: -1 if can't receive, range otherwise - if (wires.IsIndexCut(WIRE_RECEIVE)) + if (!wires || wires.IsIndexCut(WIRE_RECEIVE)) return -1 if(!listening) return -1 diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index 7bd8f6e1207..5d85ea20e2b 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -74,6 +74,12 @@ RCD src.spark_system.start() return if(3) + mode = 4 + to_chat(user, "Changed mode to 'Windows'") + if(prob(20)) + src.spark_system.start() + return + if(4) mode = 1 to_chat(user, "Changed mode to 'Floor & Walls'") if(prob(20)) @@ -88,7 +94,7 @@ RCD if(!proximity) return if(istype(A,/area/shuttle)||istype(A,/turf/space/transit)) return 0 - if(!(istype(A, /turf) || istype(A, /obj/machinery/door/airlock))) + if(!(istype(A, /turf) || istype(A, /obj/machinery/door/airlock) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/window))) return 0 switch(mode) @@ -97,7 +103,8 @@ RCD if(useResource(1, user)) to_chat(user, "Building Floor...") activate() - A:ChangeTurf(/turf/simulated/floor/plating) + var/turf/AT = A + AT.ChangeTurf(/turf/simulated/floor/plating) return 1 return 0 @@ -108,7 +115,8 @@ RCD if(do_after(user, 20, target = A)) if(!useResource(3, user)) return 0 activate() - A:ChangeTurf(/turf/simulated/wall) + var/turf/AT = A + AT.ChangeTurf(/turf/simulated/wall) return 1 return 0 @@ -136,7 +144,8 @@ RCD if(do_after(user, 40, target = A)) if(!useResource(5, user)) return 0 activate() - A:ChangeTurf(/turf/simulated/floor/plating) + var/turf/AT = A + AT.ChangeTurf(/turf/simulated/floor/plating) return 1 return 0 @@ -147,7 +156,8 @@ RCD if(do_after(user, 50, target = A)) if(!useResource(5, user)) return 0 activate() - A:ChangeTurf(/turf/space) + var/turf/AT = A + AT.ChangeTurf(/turf/space) return 1 return 0 @@ -161,7 +171,78 @@ RCD qdel(A) return 1 return 0 + + if(istype(A, /obj/structure/window)) // You mean the grille of course, do you? + A = locate(/obj/structure/grille) in A.loc + + if(istype(A, /obj/structure/grille)) + if(!checkResource(2, user)) + return 0 + to_chat(user, "Deconstructing window...") + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + if(!do_after(user, 20, target = A)) + return 0 + if(locate(/obj/structure/window/full/shuttle) in A.contents) + return 0 // Let's not give shuttle-griefers an easy time. + if(!useResource(2, user)) + return 0 + activate() + var/turf/T1 = get_turf(A) + qdel(A) + A = null + for(var/obj/structure/window/W in T1.contents) + W.disassembled = 1 + W.density = 0 + qdel(W) + for(var/cdir in cardinal) + var/turf/T2 = get_step(T1, cdir) + if(locate(/obj/structure/window/full/shuttle) in T2.contents) + continue // Shuttle windows? Nah. We don't need extra windows there. + if(!(locate(/obj/structure/grille) in T2.contents)) + continue + for(var/obj/structure/window/W in T2.contents) + if(W.dir == turn(cdir, 180)) + W.disassembled = 1 + W.density = 0 + qdel(W) + var/obj/structure/window/reinforced/W = new(T2) + W.dir = turn(cdir, 180) + return 1 return 0 + if(4) + if(istype(A, /turf/simulated/floor)) + if(locate(/obj/structure/grille) in contents) + return 0 // We already have window + if(!checkResource(2, user)) + return 0 + to_chat(user, "Constructing window...") + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + if(!do_after(user, 20, target = A)) + return 0 + if(locate(/obj/structure/grille) in A.contents) + return 0 // We already have window + if(!useResource(2, user)) + return 0 + activate() + new /obj/structure/grille(A) + for(var/obj/structure/window/W in contents) + W.disassembled = 1 // Prevent that annoying glass breaking sound + W.density = 0 + qdel(W) + for(var/cdir in cardinal) + var/turf/T = get_step(A, cdir) + if(locate(/obj/structure/grille) in T.contents) + for(var/obj/structure/window/W in T.contents) + if(W.dir == turn(cdir, 180)) + W.disassembled = 1 + W.density = 0 + qdel(W) + else // Build a window! + var/obj/structure/window/reinforced/W = new(A) + W.dir = cdir + var/turf/AT = A + AT.ChangeTurf(/turf/simulated/floor/plating) // Platings go under windows. + return 1 else to_chat(user, "ERROR: RCD in MODE: [mode] attempted use by [user]. Send this text #coderbus or an admin.") return 0 diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 3e2448fa8fe..89a8b52b8da 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -91,16 +91,16 @@ /obj/item/weapon/razor/attack(mob/living/carbon/M as mob, mob/user as mob) if(ishuman(M)) var/mob/living/carbon/human/H = M - var/obj/item/organ/external/head/C = H.organs_by_name["head"] + var/obj/item/organ/external/head/C = H.get_organ("head") var/datum/robolimb/robohead = all_robolimbs[C.model] if(user.zone_sel.selecting == "mouth") if(!get_location_accessible(H, "mouth")) to_chat(user, "The mask is in the way.") return - if((H.species && H.species.flags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... + if((C.species && C.species.flags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... to_chat(user, "You find yourself disappointed at the appalling lack of facial hair.") return - if(H.f_style == "Shaved") + if(C.f_style == "Shaved") to_chat(user, "Already clean-shaven.") return if(H == user) //shaving yourself @@ -109,7 +109,7 @@ if(do_after(user, 50, target = H)) user.visible_message("[user] shaves his facial hair clean with the [src].", \ "You finish shaving with the [src]. Fast and clean!") - H.f_style = "Shaved" + C.f_style = "Shaved" H.update_fhair() playsound(src.loc, 'sound/items/Welder2.ogg', 20, 1) else @@ -121,17 +121,17 @@ if(user_loc == user.loc && H_loc == H.loc) user.visible_message("[user] shaves off [H]'s facial hair with \the [src].", \ "You shave [H]'s facial hair clean off.") - H.f_style = "Shaved" + C.f_style = "Shaved" H.update_fhair() playsound(src.loc, 'sound/items/Welder2.ogg', 20, 1) if(user.zone_sel.selecting == "head") if(!get_location_accessible(H, "head")) to_chat(user, "The headgear is in the way.") return - if((H.species && H.species.flags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... + if((C.species && C.species.flags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'... to_chat(user, "You find yourself disappointed at the appalling lack of hair.") return - if(H.h_style == "Bald" || H.h_style == "Balding Hair" || H.h_style == "Skinhead") + if(C.h_style == "Bald" || C.h_style == "Balding Hair" || C.h_style == "Skinhead") to_chat(user, "There is not enough hair left to shave...") return if(H == user) //shaving yourself @@ -140,7 +140,7 @@ if(do_after(user, 50, target = H)) user.visible_message("[user] shaves his head with the [src].", \ "You finish shaving with the [src].") - H.h_style = "Skinhead" + C.h_style = "Skinhead" H.update_hair() playsound(src.loc, 'sound/items/Welder2.ogg', 40, 1) else @@ -152,7 +152,7 @@ if(user_loc == user.loc && H_loc == H.loc) user.visible_message("[user] shaves [H]'s head bald with \the [src]!", \ "You shave [H]'s head bald.") - H.h_style = "Skinhead" + C.h_style = "Skinhead" H.update_hair() playsound(src.loc, 'sound/items/Welder2.ogg', 40, 1) else diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 149cc03a866..a951f1ade8f 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -458,11 +458,11 @@ New() ..() var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src) - var/obj/item/weapon/reagent_containers/glass/beaker/large/B2 = new(src) + var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src) B1.reagents.add_reagent("fluorosurfactant", 40) - B2.reagents.add_reagent("water", 40) - B2.reagents.add_reagent("cleaner", 60) + B2.reagents.add_reagent("cleaner", 10) + B2.reagents.add_reagent("water", 40) //when you make pre-designed foam reactions that carry the reagents, always add water last beakers += B1 beakers += B2 diff --git a/code/game/objects/items/weapons/scissors.dm b/code/game/objects/items/weapons/scissors.dm index 806c6a5b0e5..9f0c824dead 100644 --- a/code/game/objects/items/weapons/scissors.dm +++ b/code/game/objects/items/weapons/scissors.dm @@ -30,21 +30,21 @@ //this is largely copypasted from there. //handle facial hair (if necessary) var/list/species_facial_hair = list() - var/obj/item/organ/external/head/C = H.organs_by_name["head"] + var/obj/item/organ/external/head/C = H.get_organ("head") var/datum/robolimb/robohead = all_robolimbs[C.model] if(H.gender == MALE || H.get_species() == "Vulpkanin") - if(H.species) + if(C.species) for(var/i in facial_hair_styles_list) var/datum/sprite_accessory/facial_hair/tmp_facial = facial_hair_styles_list[i] - if(H.species.name in tmp_facial.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human hair styles. - if(H.species.flags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. + if(C.species.name in tmp_facial.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human hair styles. + if(C.species.flags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. if(robohead.is_monitor) to_chat(user, "You are unable to find anything on [H]'s face worth cutting. How disappointing.") return continue //If the head DOES support human hair wigs, make sure they don't get monitor-oriented styles. species_facial_hair += i else - if(H.species.flags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. + if(C.species.flags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. if(!robohead.is_monitor) if("Human" in tmp_facial.species_allowed) species_facial_hair += i @@ -56,18 +56,18 @@ var/f_new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in species_facial_hair //handle normal hair var/list/species_hair = list() - if(H.species) + if(C.species) for(var/i in hair_styles_list) var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i] - if(H.species.name in tmp_hair.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human facial hair styles. - if(H.species.flags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. + if(C.species.name in tmp_hair.species_allowed) //If the species is allowed to have the style, add the style to the list. Or, if the character has a prosthetic head, give them the human facial hair styles. + if(C.species.flags & ALL_RPARTS) //If the character is of a species that can have full body prosthetics and their head doesn't suport human hair 'wigs', don't add the style to the list. if(robohead.is_monitor) to_chat(user, "You are unable to find anything on [H]'s head worth cutting. How disappointing.") return continue //If the head DOES support human hair wigs, make sure they don't get monitor-oriented styles. species_hair += i else - if(H.species.flags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. + if(C.species.flags & ALL_RPARTS) //If the target is of a species that can have prosthetic heads, and the head supports human hair 'wigs' AND the hair-style is human-suitable, add it to the list. if(!robohead.is_monitor) if("Human" in tmp_hair.species_allowed) species_hair += i @@ -84,11 +84,12 @@ user.visible_message("[user] stops cutting [M]'s hair.", "You stop cutting [M]'s hair.") return if(f_new_style) - H.f_style = f_new_style + C.f_style = f_new_style if(h_new_style) - H.h_style = h_new_style + C.h_style = h_new_style H.update_hair() + H.update_fhair() user.visible_message("[user] finishes cutting [M]'s hair!") /obj/item/weapon/scissors/safety //Totally safe, I assure you. diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 699f5ac85aa..d0e8d4c9c85 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -17,6 +17,7 @@ if(!AC) AC = new(src, user) AC.name = "SalonPro Nano-Mirror™" + AC.flags = APPEARANCE_ALL_BODY ui_users[user] = AC AC.ui_interact(user) diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 14bf44ff7b5..241e317c24b 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -148,6 +148,7 @@ var/send_emergency_team /client/proc/create_response_team(obj/spawn_location) var/mob/living/carbon/human/M = new(null) + var/obj/item/organ/external/head/head_organ = M.get_organ("head") response_team_members |= M var/new_gender = alert(usr, "Please select your gender.", "Character Generation", "Male", "Female") @@ -173,18 +174,18 @@ var/send_emergency_team if(prob(5)) facial_hair_style = pick(facial_hair_styles_list) - M.r_facial = hex2num(copytext(hair_c, 2, 4)) - M.g_facial = hex2num(copytext(hair_c, 4, 6)) - M.b_facial = hex2num(copytext(hair_c, 6, 8)) - M.r_hair = hex2num(copytext(hair_c, 2, 4)) - M.g_hair = hex2num(copytext(hair_c, 4, 6)) - M.b_hair = hex2num(copytext(hair_c, 6, 8)) + head_organ.r_facial = hex2num(copytext(hair_c, 2, 4)) + head_organ.g_facial = hex2num(copytext(hair_c, 4, 6)) + head_organ.b_facial = hex2num(copytext(hair_c, 6, 8)) + head_organ.r_hair = hex2num(copytext(hair_c, 2, 4)) + head_organ.g_hair = hex2num(copytext(hair_c, 4, 6)) + head_organ.b_hair = hex2num(copytext(hair_c, 6, 8)) M.r_eyes = hex2num(copytext(eye_c, 2, 4)) M.g_eyes = hex2num(copytext(eye_c, 4, 6)) M.b_eyes = hex2num(copytext(eye_c, 6, 8)) M.s_tone = skin_tone - M.h_style = hair_style - M.f_style = facial_hair_style + head_organ.h_style = hair_style + head_organ.f_style = facial_hair_style M.real_name = "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(last_names)]" M.name = M.real_name diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 6e4f58c5ab2..d7e79934389 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -142,6 +142,11 @@ var/global/nologevent = 0 if(istype(M, /mob/dead/observer)) body += "Re-incarnate | " + if(ispAI(M)) + body += "Is a pAI " + else + body += "Make pAI | " + // DNA2 - Admin Hax if(M.dna && iscarbon(M)) body += "

" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 7fb6806b5c0..090955de57a 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1142,6 +1142,28 @@ message_admins("\blue [key_name_admin(usr)] attempting to corgize [key_name_admin(H)]", 1) H.corgize() + else if(href_list["makePAI"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makePAI"]) + if(!istype(H)) + to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human") + return + + var/painame = "Default" + var/name = "" + if(alert(usr, "Do you want to set their name or let them choose their own name?", "Name Choice", "Set Name", "Let them choose") == "Set Name") + name = sanitize(copytext(input(usr, "Enter a name for the new pAI. Default name is [painame].", "pAI Name", painame),1,MAX_NAME_LEN)) + else + name = sanitize(copytext(input(H, "An admin wants to make you into a pAI. Choose a name. Default is [painame].", "pAI Name", painame),1,MAX_NAME_LEN)) + + if(!name) + name = painame + + log_admin("[key_name(usr)] attempting to pAIze [key_name(H)]") + message_admins("\blue [key_name_admin(usr)] attempting to pAIze [key_name_admin(H)]", 1) + H.paize(name) + else if(href_list["forcespeech"]) if(!check_rights(R_SERVER|R_EVENT)) return diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index e09953a81d6..46972243a06 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -498,6 +498,7 @@ client/proc/one_click_antag() /datum/admins/proc/create_vox_raider(obj/spawn_location, leader_chosen = 0) var/mob/living/carbon/human/new_vox = new(spawn_location.loc, "Vox") + var/obj/item/organ/external/head/head_organ = new_vox.get_organ("head") var/sounds = rand(2,8) var/i = 0 @@ -516,8 +517,8 @@ client/proc/one_click_antag() new_vox.add_language("Vox-pidgin") new_vox.add_language("Galactic Common") new_vox.add_language("Tradeband") - new_vox.h_style = "Short Vox Quills" - new_vox.f_style = "Shaved" + head_organ.h_style = "Short Vox Quills" + head_organ.f_style = "Shaved" for(var/obj/item/organ/external/limb in new_vox.organs) limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 043caf0ca0e..8b222116995 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1603,7 +1603,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("nanoui") nanoui_fancy = !nanoui_fancy - if("ghost_att_anim") + if("ghost_att_anim") show_ghostitem_attack = !show_ghostitem_attack if("UIcolor") @@ -1726,13 +1726,19 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.g_eyes = g_eyes character.b_eyes = b_eyes - character.r_hair = r_hair - character.g_hair = g_hair - character.b_hair = b_hair + //Head-specific + var/obj/item/organ/external/head/H = character.get_organ("head") + H.r_hair = r_hair + H.g_hair = g_hair + H.b_hair = b_hair - character.r_facial = r_facial - character.g_facial = g_facial - character.b_facial = b_facial + H.r_facial = r_facial + H.g_facial = g_facial + H.b_facial = b_facial + + H.h_style = h_style + H.f_style = f_style + //End of head-specific. character.r_skin = r_skin character.g_skin = g_skin @@ -1740,9 +1746,6 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.s_tone = s_tone - character.h_style = h_style - character.f_style = f_style - // Destroy/cyborgize organs for(var/name in organ_data) @@ -1819,10 +1822,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.socks = socks if(character.species.bodyflags & HAS_HEAD_ACCESSORY) - character.r_headacc = r_headacc - character.g_headacc = g_headacc - character.b_headacc = b_headacc - character.ha_style = ha_style + H.r_headacc = r_headacc + H.g_headacc = g_headacc + H.b_headacc = b_headacc + H.ha_style = ha_style if(character.species.bodyflags & HAS_MARKINGS) character.r_markings = r_markings character.g_markings = g_markings diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 8bda5f4c30f..0fbb39e6f1b 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -176,9 +176,11 @@ /obj/item/clothing/head/kitty/update_icon(var/mob/living/carbon/human/user) if(!istype(user)) return + var/obj/item/organ/external/head/head_organ = user.get_organ("head") + mob = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kitty") // mob2 = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kitty2") - Commented out because it seemingly does nothing. - mob.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD) + mob.Blend(rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair), ICON_ADD) // mob2.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD) - Commented out because it seemingly does nothing. var/icon/earbit = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kittyinner") @@ -201,8 +203,9 @@ /obj/item/clothing/head/kitty/mouse/update_icon(var/mob/living/carbon/human/user) if(!istype(user)) return + var/obj/item/organ/external/head/head_organ = user.get_organ("head") mob = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "mousey") - mob.Blend(rgb(user.r_hair, user.g_hair, user.b_hair), ICON_ADD) + mob.Blend(rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair), ICON_ADD) var/icon/earbit = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "mouseyinner") mob.Blend(earbit, ICON_OVERLAY) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 8264db804fd..52488051f50 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -18,16 +18,17 @@ return 1 /mob/living/carbon/human/proc/change_gender(var/gender, var/update_dna = 1) + var/obj/item/organ/external/head/H = organs_by_name["head"] if(src.gender == gender) return src.gender = gender - var/datum/sprite_accessory/hair/current_hair = hair_styles_list[h_style] + var/datum/sprite_accessory/hair/current_hair = hair_styles_list[H.h_style] if(current_hair.gender != NEUTER && current_hair.gender != src.gender) reset_head_hair() - var/datum/sprite_accessory/hair/current_fhair = facial_hair_styles_list[f_style] + var/datum/sprite_accessory/hair/current_fhair = facial_hair_styles_list[H.f_style] if(current_fhair.gender != NEUTER && current_fhair.gender != src.gender) reset_facial_hair() @@ -38,59 +39,137 @@ return 1 /mob/living/carbon/human/proc/change_hair(var/hair_style) + var/obj/item/organ/external/head/H = get_organ("head") if(!hair_style) return - if(h_style == hair_style) + if(H.h_style == hair_style) return if(!(hair_style in hair_styles_list)) return - h_style = hair_style + H.h_style = hair_style update_hair() return 1 /mob/living/carbon/human/proc/change_facial_hair(var/facial_hair_style) + var/obj/item/organ/external/head/H = get_organ("head") if(!facial_hair_style) return - if(f_style == facial_hair_style) + if(H.f_style == facial_hair_style) return if(!(facial_hair_style in facial_hair_styles_list)) return - f_style = facial_hair_style + H.f_style = facial_hair_style update_fhair() return 1 +/mob/living/carbon/human/proc/change_head_accessory(var/head_accessory_style) + var/obj/item/organ/external/head/H = get_organ("head") + if(!head_accessory_style) + return + + if(H.ha_style == head_accessory_style) + return + + if(!(head_accessory_style in head_accessory_styles_list)) + return + + H.ha_style = head_accessory_style + + update_head_accessory() + return 1 + +/mob/living/carbon/human/proc/change_markings(var/marking_style) + if(!marking_style) + return + + if(src.m_style == marking_style) + return + + if(!(marking_style in marking_styles_list)) + return + + src.m_style = marking_style + + update_markings() + return 1 + +/mob/living/carbon/human/proc/change_body_accessory(var/body_accessory_style) + var/found + if(!body_accessory_style) + return + + if(src.body_accessory) + if(src.body_accessory.name == body_accessory_style) + return + + for(var/B in body_accessory_by_name) + if(B == body_accessory_style) + src.body_accessory = body_accessory_by_name[body_accessory_style] + found = 1 + + if(!found) + return + + update_tail_layer() + return 1 + /mob/living/carbon/human/proc/reset_hair() reset_head_hair() reset_facial_hair() + reset_head_accessory() + if(m_style && m_style != "None") //Resets the markings if they were head markings. + var/datum/sprite_accessory/marking_style = marking_styles_list[m_style] + if(marking_style && marking_style.marking_location == "head") + reset_markings() /mob/living/carbon/human/proc/reset_head_hair() + var/obj/item/organ/external/head/H = get_organ("head") var/list/valid_hairstyles = generate_valid_hairstyles() - if(valid_hairstyles.len) - h_style = pick(valid_hairstyles) + H.h_style = pick(valid_hairstyles) else //this shouldn't happen - h_style = "Bald" + H.h_style = "Bald" update_hair() /mob/living/carbon/human/proc/reset_facial_hair() + var/obj/item/organ/external/head/H = get_organ("head") var/list/valid_facial_hairstyles = generate_valid_facial_hairstyles() if(valid_facial_hairstyles.len) - f_style = pick(valid_facial_hairstyles) + H.f_style = pick(valid_facial_hairstyles) else //this shouldn't happen - f_style = "Shaved" + H.f_style = "Shaved" update_fhair() +/mob/living/carbon/human/proc/reset_markings() + var/list/valid_markings = generate_valid_markings() + if(valid_markings.len) + m_style = pick(valid_markings) + else + //this shouldn't happen + m_style = "None" + update_markings() + +/mob/living/carbon/human/proc/reset_head_accessory() + var/obj/item/organ/external/head/H = get_organ("head") + var/list/valid_head_accessories = generate_valid_head_accessories() + if(valid_head_accessories.len) + H.ha_style = pick(valid_head_accessories) + else + //this shouldn't happen + H.ha_style = "None" + update_head_accessory() + /mob/living/carbon/human/proc/change_eye_color(var/red, var/green, var/blue) if(red == r_eyes && green == g_eyes && blue == b_eyes) return @@ -104,27 +183,53 @@ return 1 /mob/living/carbon/human/proc/change_hair_color(var/red, var/green, var/blue) - if(red == r_eyes && green == g_eyes && blue == b_eyes) + var/obj/item/organ/external/head/H = get_organ("head") + if(red == H.r_hair && green == H.g_hair && blue == H.b_hair) return - r_hair = red - g_hair = green - b_hair = blue + H.r_hair = red + H.g_hair = green + H.b_hair = blue update_hair() return 1 /mob/living/carbon/human/proc/change_facial_hair_color(var/red, var/green, var/blue) - if(red == r_facial && green == g_facial && blue == b_facial) + var/obj/item/organ/external/head/H = get_organ("head") + if(red == H.r_facial && green == H.g_facial && blue == H.b_facial) return - r_facial = red - g_facial = green - b_facial = blue + H.r_facial = red + H.g_facial = green + H.b_facial = blue update_fhair() return 1 +/mob/living/carbon/human/proc/change_head_accessory_color(var/red, var/green, var/blue) + var/obj/item/organ/external/head/H = get_organ("head") + if(red == H.r_headacc && green == H.g_headacc && blue == H.b_headacc) + return + + H.r_headacc = red + H.g_headacc = green + H.b_headacc = blue + + update_head_accessory() + return 1 + +/mob/living/carbon/human/proc/change_marking_color(var/red, var/green, var/blue) + if(red == r_markings && green == g_markings && blue == b_markings) + return + + r_markings = red + g_markings = green + b_markings = blue + + update_markings() + return 1 + + /mob/living/carbon/human/proc/change_skin_color(var/red, var/green, var/blue) if(red == r_skin && green == g_skin && blue == b_skin || !(species.bodyflags & HAS_SKIN_COLOR)) return @@ -170,6 +275,7 @@ /mob/living/carbon/human/proc/generate_valid_hairstyles() var/list/valid_hairstyles = new() + var/obj/item/organ/external/head/H = get_organ("head") for(var/hairstyle in hair_styles_list) var/datum/sprite_accessory/S = hair_styles_list[hairstyle] @@ -177,12 +283,11 @@ continue if(gender == FEMALE && S.gender == MALE) continue - if(species.flags & ALL_RPARTS) //If the user is a species who can have a robotic head... - var/obj/item/organ/external/head/H = organs_by_name["head"] + if(H.species.flags & ALL_RPARTS) //If the user is a species who can have a robotic head... var/datum/robolimb/robohead = all_robolimbs[H.model] if(!H) return - if(species.name in S.species_allowed) //If this is a hairstyle native to the user's species... + if(H.species.name in S.species_allowed) //If this is a hairstyle native to the user's species... if(robohead.is_monitor && (robohead.company in S.models_allowed)) //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. continue @@ -195,8 +300,8 @@ if("Human" in S.species_allowed) //If the user has a robotic head and the hairstyle can fit humans, let them use it as a wig for their humanoid robot head. valid_hairstyles += hairstyle continue - else - if(!(species.name in S.species_allowed)) //If the user is not a species who can have robotic heads, use the default handling. + else //If the user is not a species who can have robotic heads, use the default handling. + if(!(H.species.name in S.species_allowed)) //If the user's head is not of a species the hair style allows, skip it. Otherwise, add it to the list. continue valid_hairstyles += hairstyle @@ -204,6 +309,7 @@ /mob/living/carbon/human/proc/generate_valid_facial_hairstyles() var/list/valid_facial_hairstyles = new() + var/obj/item/organ/external/head/H = get_organ("head") for(var/facialhairstyle in facial_hair_styles_list) var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] @@ -211,12 +317,11 @@ continue if(gender == FEMALE && S.gender == MALE) continue - if(species.flags & ALL_RPARTS) //If the user is a species who can have a robotic head... - var/obj/item/organ/external/head/H = organs_by_name["head"] + if(H.species.flags & ALL_RPARTS) //If the user is a species who can have a robotic head... var/datum/robolimb/robohead = all_robolimbs[H.model] if(!H) continue // No head, no hair - if(species.name in S.species_allowed) //If this is a facial hair style native to the user's species... + if(H.species.name in S.species_allowed) //If this is a facial hair style native to the user's species... if(robohead.is_monitor && (robohead.company in S.models_allowed)) //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 hair styles if they do. continue @@ -231,8 +336,52 @@ valid_facial_hairstyles += facialhairstyle continue else //If the user is not a species who can have robotic heads, use the default handling. - if(!(species.name in S.species_allowed)) + if(!(H.species.name in S.species_allowed)) //If the user's head is not of a species the facial hair style allows, skip it. Otherwise, add it to the list. continue valid_facial_hairstyles += facialhairstyle return valid_facial_hairstyles + +/mob/living/carbon/human/proc/generate_valid_head_accessories() + var/list/valid_head_accessories = new() + var/obj/item/organ/external/head/H = get_organ("head") + for(var/head_accessory in head_accessory_styles_list) + var/datum/sprite_accessory/S = head_accessory_styles_list[head_accessory] + + if(!(H.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list. + continue + valid_head_accessories += head_accessory + + return valid_head_accessories + +/mob/living/carbon/human/proc/generate_valid_markings() + var/list/valid_markings = new() + var/obj/item/organ/external/head/H = get_organ("head") + for(var/marking in marking_styles_list) + var/datum/sprite_accessory/S = marking_styles_list[marking] + + if(!(species.name in S.species_allowed)) //If the user's head is not of a species the marking style allows, skip it. Otherwise, add it to the list. + continue + if(H.species.flags & ALL_RPARTS) //If the user is a species that can have a robotic head... + var/datum/robolimb/robohead = all_robolimbs[H.model] + if(!(S.models_allowed && (robohead.company in S.models_allowed))) //Make sure they don't get markings incompatible with their head. + continue + valid_markings += marking + + return valid_markings + +/mob/living/carbon/human/proc/generate_valid_body_accessories() + var/list/valid_body_accessories = new() + for(var/B in body_accessory_by_name) + var/datum/body_accessory/A = body_accessory_by_name[B] + if(check_rights(R_ADMIN, 1, src)) + valid_body_accessories = body_accessory_by_name.Copy() + else + if(!istype(A)) + valid_body_accessories += "None" //The only null entry should be the "None" option. + continue + if(!(species.name in A.allowed_species)) //If the user is not of a species the body accessory style allows, skip it. Otherwise, add it to the list. + continue + valid_body_accessories += B + + return valid_body_accessories diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index aa31c912841..fce12362d73 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -145,12 +145,13 @@ return ..(gibbed) /mob/living/carbon/human/proc/makeSkeleton() + var/obj/item/organ/external/head/H = get_organ("head") if(SKELETON in src.mutations) return - if(f_style) - f_style = "Shaved" - if(h_style) - h_style = "Bald" + if(H.f_style) + H.f_style = "Shaved" + if(H.h_style) + H.h_style = "Bald" update_fhair(0) update_hair(0) @@ -162,12 +163,13 @@ return /mob/living/carbon/human/proc/ChangeToHusk() + var/obj/item/organ/external/head/H = organs_by_name["head"] if(HUSK in mutations) return - if(f_style) - f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE - if(h_style) - h_style = "Bald" + if(H.f_style) + H.f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE + if(H.h_style) + H.h_style = "Bald" update_fhair(0) update_hair(0) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 1bb9ec062a9..eca554dcb0c 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -307,18 +307,28 @@ if (M == src) M = null - if (M) - if(src.lying || src.weakened) + if(M) + if(lying || weakened) message = "[src] flops and flails around on the floor." else message = "[src] flips in [M]'s general direction." - src.SpinAnimation(5,1) + SpinAnimation(5,1) else - if(src.lying || src.weakened) + if(lying || weakened) message = "[src] flops and flails around on the floor." else - message = "[src] does a flip!" - src.SpinAnimation(5,1) + var/obj/item/weapon/grab/G = get_active_hand() + if(G && G.affecting) + var/turf/oldloc = loc + var/turf/newloc = G.affecting.loc + if(isturf(oldloc) && isturf(newloc)) + SpinAnimation(5,1) + forceMove(newloc) + G.affecting.forceMove(oldloc) + message = "[src] flips over [G.affecting]!" + else + message = "[src] does a flip!" + SpinAnimation(5,1) if ("aflap", "aflaps") if (!src.restrained()) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 3e5cb90f380..90fed057057 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -74,38 +74,30 @@ status_flags = GODMODE|CANPUSH /mob/living/carbon/human/skrell/New(var/new_loc) - h_style = "Skrell Male Tentacles" ..(new_loc, "Skrell") /mob/living/carbon/human/tajaran/New(var/new_loc) - ha_style = "Tajaran Ears" ..(new_loc, "Tajaran") /mob/living/carbon/human/vulpkanin/New(var/new_loc) - h_style = "Bald" ..(new_loc, "Vulpkanin") /mob/living/carbon/human/unathi/New(var/new_loc) - h_style = "Unathi Horns" ..(new_loc, "Unathi") /mob/living/carbon/human/vox/New(var/new_loc) - h_style = "Short Vox Quills" ..(new_loc, "Vox") /mob/living/carbon/human/voxarmalis/New(var/new_loc) - h_style = "Bald" ..(new_loc, "Vox Armalis") /mob/living/carbon/human/skeleton/New(var/new_loc) - h_style = "Bald" ..(new_loc, "Skeleton") /mob/living/carbon/human/kidan/New(var/new_loc) ..(new_loc, "Kidan") /mob/living/carbon/human/plasma/New(var/new_loc) - h_style = "Bald" ..(new_loc, "Plasmaman") /mob/living/carbon/human/slime/New(var/new_loc) @@ -121,31 +113,24 @@ ..(new_loc, "Human") /mob/living/carbon/human/diona/New(var/new_loc) - h_style = "Bald" ..(new_loc, "Diona") /mob/living/carbon/human/machine/New(var/new_loc) - h_style = "blue IPC screen" ..(new_loc, "Machine") /mob/living/carbon/human/shadow/New(var/new_loc) - h_style = "Bald" ..(new_loc, "Shadow") /mob/living/carbon/human/golem/New(var/new_loc) - h_style = "Bald" ..(new_loc, "Golem") /mob/living/carbon/human/wryn/New(var/new_loc) - h_style = "Antennae" ..(new_loc, "Wryn") /mob/living/carbon/human/nucleation/New(var/new_loc) - h_style = "Nucleation Crystals" ..(new_loc, "Nucleation") /mob/living/carbon/human/drask/New(var/new_loc) - h_style = "Bald" ..(new_loc, "Drask") /mob/living/carbon/human/monkey/New(var/new_loc) @@ -1505,6 +1490,15 @@ species.create_organs(src) + //Handle default hair/head accessories for created mobs. + var/obj/item/organ/external/head/H = get_organ("head") + if(species.default_hair) + H.h_style = species.default_hair + if(species.default_fhair) + H.f_style = species.default_fhair + if(species.default_headacc) + H.ha_style = species.default_headacc + if(!dna) dna = new /datum/dna(null) dna.species = species.name @@ -1601,9 +1595,8 @@ return if(species.flags & ALL_RPARTS) //If they can have a fully cybernetic body... - var/obj/item/organ/external/head/H = organs_by_name["head"] - var/datum/robolimb/robohead = all_robolimbs[H.model] - if(!H) + var/datum/robolimb/robohead = all_robolimbs[head_organ.model] + if(!head_organ) return if(!robohead.is_monitor) //If they've got a prosthetic head and it isn't a monitor, they've no screen to adjust. Instead, let them change the colour of their optics! var/optic_colour = input(src, "Select optic colour", rgb(r_markings, g_markings, b_markings)) as color|null @@ -1620,15 +1613,15 @@ var/list/hair = list() for(var/i in hair_styles_list) var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i] - if((species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. + if((head_organ.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. hair += i - var/new_style = input(src, "Select a monitor display", "Monitor Display", h_style) as null|anything in hair + var/new_style = input(src, "Select a monitor display", "Monitor Display", head_organ.h_style) as null|anything in hair if(incapacitated()) to_chat(src, "You were interrupted while changing your monitor display.") return if(new_style) - h_style = new_style + head_organ.h_style = new_style update_hair() diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index e2ebed386b3..6f106f5e125 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -9,24 +9,6 @@ var/global/default_martial_art = new/datum/martial_art var/b_markings = 0 var/m_style = "None" - //Hair colour and style - var/r_hair = 0 - var/g_hair = 0 - var/b_hair = 0 - var/h_style = "Bald" - - //Head accessory colour and style - var/r_headacc = 0 - var/g_headacc = 0 - var/b_headacc = 0 - var/ha_style = "None" - - //Facial hair colour and style - var/r_facial = 0 - var/g_facial = 0 - var/b_facial = 0 - var/f_style = "Shaved" - //Eye colour var/r_eyes = 0 var/g_eyes = 0 diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm index a7735a00db9..5642eedbcbe 100644 --- a/code/modules/mob/living/carbon/human/species/apollo.dm +++ b/code/modules/mob/living/carbon/human/species/apollo.dm @@ -45,6 +45,8 @@ base_color = "#704300" flesh_color = "#704300" blood_color = "#FFFF99" + //Default styles for created mobs. + default_hair = "Antennae" /datum/species/wryn/handle_death(var/mob/living/carbon/human/H) @@ -54,6 +56,7 @@ to_chat(C, "It feels like part of you has died.") /datum/species/wryn/handle_attack_hand(var/mob/living/carbon/human/H, var/mob/living/carbon/human/M) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") if(M.a_intent == I_HARM) if(H.handcuffed) if(!H.get_int_organ(/obj/item/organ/internal/wryn/hivenode)) return @@ -71,7 +74,7 @@ to_chat(M, "You hear a loud crunch as you mercilessly pull off [H]'s antennae.") to_chat(H, "You hear a loud crunch as your antennae is ripped off your head by [M].") to_chat(H, "It's so quiet...") - H.h_style = "Bald" + head_organ.h_style = "Bald" H.update_hair() M.attack_log += text("\[[time_stamp()]\] removed antennae [H.name] ([H.ckey])") @@ -87,7 +90,7 @@ blurb = "A sub-race of unforunates who have been exposed to too much supermatter radiation. As a result, \ supermatter crystal clusters have begun to grow across their bodies. Research to find a cure for this ailment \ has been slow, and so this is a common fate for veteran engineers. The supermatter crystals produce oxygen, \ - negating the need for the individual to breath. Their massive change in biology, however, renders most medicines \ + negating the need for the individual to breathe. Their massive change in biology, however, renders most medicines \ obselete. Ionizing radiation seems to cause resonance in some of their crystals, which seems to encourage regeneration \ and produces a calming effect on the individual. Nucleations are highly stigmatized, and are treated much in the same \ way as lepers were back on Earth." @@ -97,6 +100,9 @@ flags = IS_WHITELISTED | NO_BREATHE | NO_BLOOD | NO_PAIN | HAS_LIPS | NO_SCAN dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet + //Default styles for created mobs. + default_hair = "Nucleation Crystals" + reagent_tag = PROCESS_ORG has_organ = list( "heart" = /obj/item/organ/internal/heart, diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index f3e8793fed1..922810e758d 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -6,7 +6,7 @@ deform = 'icons/mob/human_races/r_golem.dmi' default_language = "Galactic Common" - flags = NO_BREATHE | NO_BLOOD | RADIMMUNE + flags = NO_BREATHE | NO_BLOOD | RADIMMUNE | NOGUNS virus_immune = 1 dietflags = DIET_OMNI //golems can eat anything because they are magic or something reagent_tag = PROCESS_ORG diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm index 72972f98baf..dffc73d4e1d 100644 --- a/code/modules/mob/living/carbon/human/species/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/monkey.dm @@ -34,8 +34,6 @@ brute_mod = 1.5 burn_mod = 1.5 - flags = IS_RESTRICTED - /datum/species/monkey/handle_npc(var/mob/living/carbon/human/H) if(H.stat != CONSCIOUS) return diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 03091a7e50f..7430dde4331 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -118,6 +118,11 @@ var/male_scream_sound = 'sound/goonstation/voice/male_scream.ogg' var/female_scream_sound = 'sound/goonstation/voice/female_scream.ogg' + //Default hair/headacc style vars. + var/default_hair = "Bald" //Default hair style for newly created humans unless otherwise set. + var/default_fhair = "Shaved" //Default facial hair style for newly created humans unless otherwise set. + var/default_headacc = "None" //Default head accessory style for newly created humans unless otherwise set. + // Determines the organs that the species spawns with and var/list/has_organ = list( // which required-organ checks are conducted. "heart" = /obj/item/organ/internal/heart, @@ -158,7 +163,6 @@ /datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. - for(var/obj/item/organ/internal/iorgan in H.internal_organs) if(iorgan in H.internal_organs) qdel(iorgan) diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index bccd2a1ffdf..19e48ba5fc0 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -55,6 +55,8 @@ flesh_color = "#34AF10" reagent_tag = PROCESS_ORG base_color = "#066000" + //Default styles for created mobs. + default_hair = "Unathi Horns" allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken, /mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) @@ -109,6 +111,8 @@ reagent_tag = PROCESS_ORG flesh_color = "#AFA59E" base_color = "#333333" + //Default styles for created mobs. + default_headacc = "Tajaran Ears" allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/chick, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) @@ -189,6 +193,8 @@ dietflags = DIET_HERB flesh_color = "#8CD7A3" blood_color = "#1D2CBF" + //Default styles for created mobs. + default_hair = "Skrell Male Tentacles" reagent_tag = PROCESS_ORG suicide_messages = list( @@ -251,6 +257,8 @@ blood_color = "#2299FC" flesh_color = "#808D11" + //Default styles for created mobs. + default_hair = "Short Vox Quills" reagent_tag = PROCESS_ORG scream_verb = "shrieks" @@ -751,6 +759,8 @@ dietflags = 0 //IPCs can't eat, so no diet blood_color = "#1F181F" flesh_color = "#AAAAAA" + //Default styles for created mobs. + default_hair = "Blue IPC Screen" virus_immune = 1 can_revive_by_healing = 1 reagent_tag = PROCESS_SYN @@ -791,6 +801,10 @@ ) /datum/species/machine/handle_death(var/mob/living/carbon/human/H) - H.h_style = "" + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + head_organ.h_style = "Bald" + head_organ.f_style = "Shaved" spawn(100) - if(H) H.update_hair() + if(H) + H.update_hair() + H.update_fhair() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 85fff9e6ead..1b5f6c25735 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -393,13 +393,13 @@ var/global/list/damage_icon_parts = list() //base icons var/icon/head_accessory_standing = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") - if(ha_style && (src.species.bodyflags & HAS_HEAD_ACCESSORY)) - var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[ha_style] + if(head_organ.ha_style && (head_organ.species.bodyflags & HAS_HEAD_ACCESSORY)) + var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[head_organ.ha_style] if(head_accessory_style && head_accessory_style.species_allowed) - if(src.species.name in head_accessory_style.species_allowed) + if(head_organ.species.name in head_accessory_style.species_allowed) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") if(head_accessory_style.do_colouration) - head_accessory_s.Blend(rgb(r_headacc, g_headacc, b_headacc), ICON_ADD) + head_accessory_s.Blend(rgb(head_organ.r_headacc, head_organ.g_headacc, head_organ.b_headacc), ICON_ADD) head_accessory_standing = head_accessory_s //head_accessory_standing.Blend(head_accessory_s, ICON_OVERLAY) //Having it this way preserves animations. Useful for animated antennae. else @@ -429,17 +429,17 @@ var/global/list/damage_icon_parts = list() var/icon/hair_standing = new /icon('icons/mob/human_face.dmi',"bald_s") //var/icon/debrained_s = new /icon("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s") - if(h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic()))) - var/datum/sprite_accessory/hair_style = hair_styles_list[h_style] + if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic()))) + var/datum/sprite_accessory/hair_style = hair_styles_list[head_organ.h_style] //if(!src.get_int_organ(/obj/item/organ/internal/brain) && src.get_species() != "Machine" )//make it obvious we have NO BRAIN // hair_standing.Blend(debrained_s, ICON_OVERLAY) if(hair_style && hair_style.species_allowed) - if((src.species.name in hair_style.species_allowed) || (src.species.flags & ALL_RPARTS)) + if((head_organ.species.name in hair_style.species_allowed) || (head_organ.species.flags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(src.get_species() == "Slime People") // I am el worstos + if(head_organ.species.name == "Slime People") // I am el worstos hair_s.Blend(rgb(r_skin, g_skin, b_skin, 160), ICON_AND) else if(hair_style.do_colouration) - hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD) + hair_s.Blend(rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair), ICON_ADD) hair_standing = hair_s //hair_standing.Blend(hair_s, ICON_OVERLAY) //Having it this way preserves animations. Useful for IPC screens. @@ -470,15 +470,15 @@ var/global/list/damage_icon_parts = list() //base icons var/icon/face_standing = new /icon('icons/mob/human_face.dmi',"bald_s") - if(f_style) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] + if(head_organ.f_style) + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[head_organ.f_style] if(facial_hair_style && facial_hair_style.species_allowed) - if((src.species.name in facial_hair_style.species_allowed) || (src.species.flags & ALL_RPARTS)) + if((head_organ.species.name in facial_hair_style.species_allowed) || (head_organ.species.flags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(src.get_species() == "Slime People") // I am el worstos + if(head_organ.species.name == "Slime People") // I am el worstos facial_s.Blend(rgb(r_skin, g_skin, b_skin, 160), ICON_AND) else if(facial_hair_style.do_colouration) - facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) + facial_s.Blend(rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial), ICON_ADD) face_standing.Blend(facial_s, ICON_OVERLAY) else //warning("Invalid f_style for [species.name]: [f_style]") @@ -1265,22 +1265,23 @@ var/global/list/damage_icon_parts = list() //gender no longer matters for the mouth, although there should probably be seperate base head icons. // var/g = "m" // if (gender == FEMALE) g = "f" - + var/obj/item/organ/external/head/H = get_organ("head") //base icons var/icon/face_lying = new /icon('icons/mob/human_face.dmi',"bald_l") - if(f_style) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] + + if(H.f_style) + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style] if(facial_hair_style) var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l") - facial_l.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD) + facial_l.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD) face_lying.Blend(facial_l, ICON_OVERLAY) - if(h_style) - var/datum/sprite_accessory/hair_style = hair_styles_list[h_style] + if(H.h_style) + var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style] if(hair_style) var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l") - hair_l.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD) + hair_l.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD) face_lying.Blend(hair_l, ICON_OVERLAY) //Eyes diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm index 08f5089a200..1ad57bd787d 100644 --- a/code/modules/mob/living/carbon/superheroes.dm +++ b/code/modules/mob/living/carbon/superheroes.dm @@ -148,6 +148,7 @@ /obj/effect/proc_holder/spell/targeted/recruit/cast(list/targets) for(var/mob/living/carbon/human/target in targets) + var/obj/item/organ/external/head/head_organ = target.get_organ("head") if(ticker.mode.greyshirts.len >= 3) to_chat(usr, "You have already recruited the maximum number of henchmen.") if(!in_range(usr, target)) @@ -210,8 +211,8 @@ to_chat(target, "You may not harm other Greyshirt or [usr]. However, you do not need to obey other Greyshirts.") ticker.mode.greyshirts += target.mind target.set_species("Human") - target.h_style = "Bald" - target.f_style = "Shaved" + head_organ.h_style = "Bald" + head_organ.f_style = "Shaved" target.s_tone = 35 target.r_eyes = 1 target.b_eyes = 1 diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index e4b7f983b9d..71d80df9e02 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -142,7 +142,7 @@ if(c.can_use()) cameras += c - for(var/turf/t in block(locate(x, y, z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z))) + for(var/turf/t in block(locate(max(x, 1), max(y, 1), max(z, 1)), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z))) turfs[t] = t for(var/camera in cameras) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 3534bbf55b2..80bcbc679f0 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -492,7 +492,7 @@ if(reagent_id == "internal_beaker") if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume) var/fraction = min(injection_amount/reagent_glass.reagents.total_volume, 1) - reagent_glass.reagents.reaction(patient, 2, fraction) + reagent_glass.reagents.reaction(patient, INGEST, fraction) reagent_glass.reagents.trans_to(patient, injection_amount) //Inject from beaker instead. else patient.reagents.add_reagent(reagent_id,injection_amount) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index ffb6f6c13b8..c427f6e7a50 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -88,13 +88,17 @@ stat("Time To Start:", "DELAYED") if(ticker.current_state == GAME_STATE_PREGAME) - stat("Players: [totalPlayers]", "Players Ready: [totalPlayersReady]") + stat("Players:", "[totalPlayers]") + if(client.holder) + stat("Players Ready:", "[totalPlayersReady]") totalPlayers = 0 totalPlayersReady = 0 for(var/mob/new_player/player in player_list) - stat("[player.key]", (player.ready)?("(Playing)"):(null)) + if(client.holder) + stat("[player.key]", (player.ready)?("(Playing)"):(null)) totalPlayers++ - if(player.ready)totalPlayersReady++ + if(player.ready) + totalPlayersReady++ /mob/new_player/Topic(href, href_list[]) if(!client) return 0 diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index e0fbfcdf91b..93797b5bb17 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -886,12 +886,12 @@ species_allowed = list("Vox") vox_quills_fluff - name = "Fluffy Quills" + name = "Fluffy Vox Quills" icon_state = "vox_afro" species_allowed = list("Vox") vox_quills_mohawk - name = "Quill Mohawk" + name = "Vox Quill Mohawk" icon_state = "vox_mohawk" species_allowed = list("Vox") @@ -910,6 +910,11 @@ icon_state = "vox_nights" species_allowed = list("Vox") + vox_razor + name = "Vox Razorback" + icon_state = "vox_razor" + species_allowed = list("Vox") + // Apollo-specific //Wryn antennae @@ -1893,22 +1898,22 @@ icon_state = "markings_tiger" /datum/sprite_accessory/body_markings/tigerhead - name = "Tiger Body + Head" + name = "Tiger Body and Head" species_allowed = list("Unathi", "Tajaran", "Vulpkanin") icon_state = "markings_tigerhead" /datum/sprite_accessory/body_markings/tigerheadface_taj - name = "Tajaran Tiger Body + Head + Face" + name = "Tajaran Tiger Body, Head and Face" species_allowed = list("Tajaran") icon_state = "markings_tigerheadface_taj" /datum/sprite_accessory/body_markings/tigerheadface_vulp - name = "Vulpkanin Tiger Body + Head + Face" + name = "Vulpkanin Tiger Body, Head and Face" species_allowed = list("Vulpkanin") icon_state = "markings_tigerheadface_vulp" /datum/sprite_accessory/body_markings/tigerheadface_una - name = "Unathi Tiger Body + Head + Face" + name = "Unathi Tiger Body, Head and Face" species_allowed = list("Unathi") icon_state = "markings_tigerheadface_una" diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index ac3dd8af716..ea70bbe88ac 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -319,6 +319,35 @@ qdel(src) + +/mob/living/carbon/human/proc/paize(var/name) + if(notransform) + return + for(var/obj/item/W in src) + unEquip(W) + regenerate_icons() + notransform = 1 + canmove = 0 + icon = null + invisibility = 101 + for(var/t in organs) //this really should not be necessary + qdel(t) + + var/obj/item/device/paicard/card = new(loc) + var/mob/living/silicon/pai/pai = new(card) + pai.key = key + card.setPersonality(pai) + + pai.name = name + pai.real_name = name + card.name = name + + to_chat(pai, "You have become a pAI! Your name is [pai.name].") + pai.update_pipe_vision() + spawn(0)//To prevent the proc from returning null. + qdel(src) + return + /mob/proc/safe_respawn(var/MP) if(!MP) return 0 diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 606dcade9c9..583b68b3dc6 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -2,9 +2,13 @@ name = "Appearance Editor" var/flags = APPEARANCE_ALL_HAIR var/mob/living/carbon/human/owner = null + var/obj/item/organ/external/head/head_organ = null var/list/valid_species = list() var/list/valid_hairstyles = list() var/list/valid_facial_hairstyles = list() + var/list/valid_head_accessories = list() + var/list/valid_marking_styles = list() + var/list/valid_body_accessories = list() var/check_whitelist var/list/whitelist @@ -13,6 +17,7 @@ /datum/nano_module/appearance_changer/New(var/location, var/mob/living/carbon/human/H, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list()) ..() owner = H + head_organ = owner.get_organ("head") src.check_whitelist = check_species_whitelist src.whitelist = species_whitelist src.blacklist = species_blacklist @@ -54,7 +59,7 @@ return 1 if(href_list["hair_color"]) if(can_change(APPEARANCE_HAIR_COLOR)) - var/new_hair = input("Please select hair color.", "Hair Color", rgb(owner.r_hair, owner.g_hair, owner.b_hair)) as color|null + var/new_hair = input("Please select hair color.", "Hair Color", rgb(head_organ.r_hair, head_organ.g_hair, head_organ.b_hair)) as color|null if(new_hair && can_still_topic(state)) var/r_hair = hex2num(copytext(new_hair, 2, 4)) var/g_hair = hex2num(copytext(new_hair, 4, 6)) @@ -69,7 +74,7 @@ return 1 if(href_list["facial_hair_color"]) if(can_change(APPEARANCE_FACIAL_HAIR_COLOR)) - var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(owner.r_facial, owner.g_facial, owner.b_facial)) as color|null + var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(head_organ.r_facial, head_organ.g_facial, head_organ.b_facial)) as color|null if(new_facial && can_still_topic(state)) var/r_facial = hex2num(copytext(new_facial, 2, 4)) var/g_facial = hex2num(copytext(new_facial, 4, 6)) @@ -87,6 +92,41 @@ if(owner.change_eye_color(r_eyes, g_eyes, b_eyes)) update_dna() return 1 + if(href_list["head_accessory"]) + if(can_change_head_accessory() && (href_list["head_accessory"] in valid_head_accessories)) + if(owner.change_head_accessory(href_list["head_accessory"])) + update_dna() + return 1 + if(href_list["head_accessory_color"]) + if(can_change_head_accessory()) + var/new_head_accessory = input("Please select head accessory color.", "Head Accessory Color", rgb(head_organ.r_headacc, head_organ.g_headacc, head_organ.b_headacc)) as color|null + if(new_head_accessory && can_still_topic(state)) + var/r_headacc = hex2num(copytext(new_head_accessory, 2, 4)) + var/g_headacc = hex2num(copytext(new_head_accessory, 4, 6)) + var/b_headacc = hex2num(copytext(new_head_accessory, 6, 8)) + if(owner.change_head_accessory_color(r_headacc, g_headacc, b_headacc)) + update_dna() + return 1 + if(href_list["marking"]) + if(can_change_markings() && (href_list["marking"] in valid_marking_styles)) + if(owner.change_markings(href_list["marking"])) + update_dna() + return 1 + if(href_list["marking_color"]) + if(can_change_markings()) + var/new_markings = input("Please select marking color.", "Marking Color", rgb(owner.r_markings, owner.g_markings, owner.b_markings)) as color|null + if(new_markings && can_still_topic(state)) + var/r_markings = hex2num(copytext(new_markings, 2, 4)) + var/g_markings = hex2num(copytext(new_markings, 4, 6)) + var/b_markings = hex2num(copytext(new_markings, 6, 8)) + if(owner.change_marking_color(r_markings, g_markings, b_markings)) + update_dna() + return 1 + if(href_list["body_accessory"]) + if(can_change_body_accessory() && (href_list["body_accessory"] in valid_body_accessories)) + if(owner.change_body_accessory(href_list["body_accessory"])) + update_dna() + return 1 return 0 @@ -107,13 +147,21 @@ data["change_skin_tone"] = can_change_skin_tone() data["change_skin_color"] = can_change_skin_color() data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR) + data["change_head_accessory"] = can_change_head_accessory() + if(data["change_head_accessory"]) + var/head_accessory_styles[0] + for(var/head_accessory_style in valid_head_accessories) + head_accessory_styles[++head_accessory_styles.len] = list("headaccessorystyle" = head_accessory_style) + data["head_accessory_styles"] = head_accessory_styles + data["head_accessory_style"] = head_organ.ha_style + data["change_hair"] = can_change(APPEARANCE_HAIR) if(data["change_hair"]) var/hair_styles[0] for(var/hair_style in valid_hairstyles) hair_styles[++hair_styles.len] = list("hairstyle" = hair_style) data["hair_styles"] = hair_styles - data["hair_style"] = owner.h_style + data["hair_style"] = head_organ.h_style data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR) if(data["change_facial_hair"]) @@ -121,10 +169,31 @@ for(var/facial_hair_style in valid_facial_hairstyles) facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style) data["facial_hair_styles"] = facial_hair_styles - data["facial_hair_style"] = owner.f_style + data["facial_hair_style"] = head_organ.f_style + data["change_markings"] = can_change_markings() + if(data["change_markings"]) + var/marking_styles[0] + for(var/marking_style in valid_marking_styles) + marking_styles[++marking_styles.len] = list("markingstyle" = marking_style) + data["marking_styles"] = marking_styles + data["marking_style"] = owner.m_style + + data["change_body_accessory"] = can_change_body_accessory() + if(data["change_body_accessory"]) + var/body_accessory_styles[0] + for(var/body_accessory_style in valid_body_accessories) + body_accessory_styles[++body_accessory_styles.len] = list("bodyaccessorystyle" = body_accessory_style) + data["body_accessory_styles"] = body_accessory_styles + var/datum/body_accessory/BA + if(owner.body_accessory) + BA = owner.body_accessory.name + data["body_accessory_style"] = BA + + data["change_head_accessory_color"] = can_change_head_accessory() data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) + data["change_marking_color"] = can_change_markings() ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src]", 800, 450, state = state) @@ -145,10 +214,22 @@ /datum/nano_module/appearance_changer/proc/can_change_skin_color() return owner && (flags & APPEARANCE_SKIN) && (owner.species.bodyflags & HAS_SKIN_COLOR) +/datum/nano_module/appearance_changer/proc/can_change_head_accessory() + return owner && (flags & APPEARANCE_HEAD_ACCESSORY) && (head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) + +/datum/nano_module/appearance_changer/proc/can_change_markings() + return owner && (flags & APPEARANCE_MARKINGS) && (owner.species.bodyflags & HAS_MARKINGS) + +/datum/nano_module/appearance_changer/proc/can_change_body_accessory() + return owner && (flags & APPEARANCE_BODY_ACCESSORY) && (owner.species.bodyflags & HAS_TAIL) + /datum/nano_module/appearance_changer/proc/cut_and_generate_data() // Making the assumption that the available species remain constant + valid_hairstyles.Cut() valid_facial_hairstyles.Cut() - valid_facial_hairstyles.Cut() + valid_head_accessories.Cut() + valid_marking_styles.Cut() + valid_body_accessories.Cut() generate_data() /datum/nano_module/appearance_changer/proc/generate_data() @@ -158,4 +239,10 @@ valid_species = owner.generate_valid_species(check_whitelist, whitelist, blacklist) if(!valid_hairstyles.len || !valid_facial_hairstyles.len) valid_hairstyles = owner.generate_valid_hairstyles() - valid_facial_hairstyles = owner.generate_valid_facial_hairstyles() \ No newline at end of file + valid_facial_hairstyles = owner.generate_valid_facial_hairstyles() + if(!valid_head_accessories.len) + valid_head_accessories = owner.generate_valid_head_accessories() + if(!valid_marking_styles.len) + valid_marking_styles = owner.generate_valid_markings() + if(!valid_body_accessories.len) + valid_body_accessories = owner.generate_valid_body_accessories() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index a4858a4a8c8..cb4f21d2497 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -134,11 +134,8 @@ return if(ishuman(user)) var/mob/living/carbon/human/H = user - if(H.get_species() == "Golem") - to_chat(user, "Your metal fingers don't fit in the trigger guard!") - return - if(H.get_species() == "Shadowling") - to_chat(user, "The muzzle flash would cause damage to your form!") + if(H.species.flags & NOGUNS) + to_chat(user, "Your fingers don't fit in the trigger guard!") return if(H.martial_art && H.martial_art.name == "The Sleeping Carp") //great dishonor to famiry to_chat(user, "Use of ranged weaponry would bring dishonor to the clan.") diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 1b2e9a0b3d4..9be9ea9c124 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -387,45 +387,48 @@ var/const/INGEST = 2 can_process = 1 return can_process -/datum/reagents/proc/reaction(var/atom/A, var/method=TOUCH, var/volume_modifier=0) - +/datum/reagents/proc/reaction(atom/A, method=TOUCH, volume_modifier = 1) switch(method) if(TOUCH) for(var/datum/reagent/R in reagent_list) if(ismob(A)) - spawn(0) - if(!R) return - var/check = reaction_check(A, R) - if(!check) - continue - else - R.reaction_mob(A, TOUCH, R.volume+volume_modifier) + if(!R) + return + var/check = reaction_check(A, R) + if(!check) + continue + else + R.reaction_mob(A, TOUCH, R.volume*volume_modifier) if(isturf(A)) - spawn(0) - if(!R) return - else R.reaction_turf(A, R.volume+volume_modifier) + if(!R) + return + else + R.reaction_turf(A, R.volume*volume_modifier) if(isobj(A)) - spawn(0) - if(!R) return - else R.reaction_obj(A, R.volume+volume_modifier) + if(!R) + return + else + R.reaction_obj(A, R.volume*volume_modifier) if(INGEST) for(var/datum/reagent/R in reagent_list) if(ismob(A) && R) - spawn(0) - if(!R) return - var/check = reaction_check(A, R) - if(!check) - continue - else - R.reaction_mob(A, INGEST, R.volume+volume_modifier) + if(!R) + return + var/check = reaction_check(A, R) + if(!check) + continue + else + R.reaction_mob(A, INGEST, R.volume*volume_modifier) if(isturf(A) && R) - spawn(0) - if(!R) return - else R.reaction_turf(A, R.volume+volume_modifier) + if(!R) + return + else + R.reaction_turf(A, R.volume*volume_modifier) if(isobj(A) && R) - spawn(0) - if(!R) return - else R.reaction_obj(A, R.volume+volume_modifier) + if(!R) + return + else + R.reaction_obj(A, R.volume*volume_modifier) return /datum/reagents/proc/add_reagent_list(list/list_reagents, list/data=null) // Like add_reagent but you can enter a list. Format it like this: list("toxin" = 10, "beer" = 15) diff --git a/code/modules/reagents/newchem/drugs.dm b/code/modules/reagents/newchem/drugs.dm index 127a37593d1..62daeee99a3 100644 --- a/code/modules/reagents/newchem/drugs.dm +++ b/code/modules/reagents/newchem/drugs.dm @@ -337,9 +337,10 @@ var/check = rand(0,100) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(check < 8 && H.h_style != "Very Long Beard") - H.h_style = "Very Long Hair" - H.f_style = "Very Long Beard" + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + if(check < 8 && head_organ.h_style != "Very Long Beard") + head_organ.h_style = "Very Long Hair" + head_organ.f_style = "Very Long Beard" H.update_hair() H.update_fhair() H.visible_message("[H] has a wild look in their eyes!") diff --git a/code/modules/reagents/newchem/other.dm b/code/modules/reagents/newchem/other.dm index 7ef7dff6ff5..1e31ba5b506 100644 --- a/code/modules/reagents/newchem/other.dm +++ b/code/modules/reagents/newchem/other.dm @@ -198,12 +198,13 @@ datum/reagent/hair_dye datum/reagent/hair_dye/reaction_mob(var/mob/living/M, var/volume) if(M && ishuman(M)) var/mob/living/carbon/human/H = M - H.r_facial = rand(0,255) - H.g_facial = rand(0,255) - H.b_facial = rand(0,255) - H.r_hair = rand(0,255) - H.g_hair = rand(0,255) - H.b_hair = rand(0,255) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + head_organ.r_facial = rand(0,255) + head_organ.g_facial = rand(0,255) + head_organ.b_facial = rand(0,255) + head_organ.r_hair = rand(0,255) + head_organ.g_hair = rand(0,255) + head_organ.b_hair = rand(0,255) H.update_hair() H.update_fhair() ..() @@ -228,8 +229,9 @@ datum/reagent/hairgrownium datum/reagent/hairgrownium/reaction_mob(var/mob/living/M, var/volume) if(M && ishuman(M)) var/mob/living/carbon/human/H = M - H.h_style = random_hair_style(H.gender, H.species) - H.f_style = random_facial_hair_style(H.gender, H.species) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + head_organ.h_style = random_hair_style(H.gender, head_organ.species.name) + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.species.name) H.update_hair() H.update_fhair() ..() @@ -252,12 +254,21 @@ datum/reagent/super_hairgrownium result_amount = 3 mix_message = "The liquid becomes amazingly furry and smells peculiar." -datum/reagent/super_hairgrownium/on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom +datum/reagent/super_hairgrownium/reaction_mob(var/mob/living/M, var/volume) if(M && ishuman(M)) var/mob/living/carbon/human/H = M - H.h_style = "Very Long Hair" - H.f_style = "Very Long Beard" + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + var/datum/sprite_accessory/tmp_hair_style = hair_styles_list["Very Long Hair"] + var/datum/sprite_accessory/tmp_facial_hair_style = facial_hair_styles_list["Very Long Beard"] + + if(head_organ.species.name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them. + head_organ.h_style = "Very Long Hair" + else //Otherwise, give them a random hair style. + head_organ.h_style = random_hair_style(H.gender, head_organ.species.name) + if(head_organ.species.name in tmp_facial_hair_style.species_allowed) //If 'Very Long Beard' is a style the person's species can have, give it to them. + head_organ.f_style = "Very Long Beard" + else //Otherwise, give them a random facial hair style. + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.species.name) H.update_hair() H.update_fhair() if(!H.wear_mask || H.wear_mask && !istype(H.wear_mask, /obj/item/clothing/mask/fakemoustache)) diff --git a/code/modules/reagents/newchem/pyro.dm b/code/modules/reagents/newchem/pyro.dm index b4070440ab3..655b8e996eb 100644 --- a/code/modules/reagents/newchem/pyro.dm +++ b/code/modules/reagents/newchem/pyro.dm @@ -293,7 +293,7 @@ datum/reagent/blackpowder/reaction_turf(var/turf/T, var/volume) //oh shit required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1) result_amount = 1 mix_message = "The mixture quickly turns into a pall of smoke!" - var/forbidden_reagents = list("sugar", "phosphorus", "potassium") //Do not transfer this stuff through smoke. + var/forbidden_reagents = list("sugar", "phosphorus", "potassium", "stimulants") //Do not transfer this stuff through smoke. /datum/chemical_reaction/smoke/on_reaction(var/datum/reagents/holder, var/created_volume) for(var/f_reagent in forbidden_reagents) @@ -325,7 +325,7 @@ datum/reagent/blackpowder/reaction_turf(var/turf/T, var/volume) //oh shit min_temp = 374 secondary = 1 result_amount = 1 - forbidden_reagents = list() + forbidden_reagents = list("stimulants") mix_sound = null /datum/reagent/sonic_powder diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm index b85d63fac2b..273ccb67d0e 100644 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ b/code/modules/scripting/Implementations/Telecomms.dm @@ -60,6 +60,9 @@ return interpreter.container = src + + interpreter.CreateGlobalScope() // Reset the variables. + interpreter.curScope = interpreter.globalScope interpreter.SetVar("PI", 3.141592653) // value of pi interpreter.SetVar("E", 2.718281828) // value of e @@ -127,7 +130,7 @@ @param time: time to sleep in deciseconds (1/10th second) */ - interpreter.SetProc("sleep", /proc/delay) + interpreter.SetProc("sleep", "delay", signal, list("time")) /* -> Replaces a string with another string @@ -255,6 +258,28 @@ signal.data["reject"] = 1 /* -- Actual language proc code -- */ +/datum/signal/proc/delay(var/time) + var/obj/machinery/telecomms/server/S = data["server"] + var/datum/n_Interpreter/TCS_Interpreter/interpreter = S.Compiler.interpreter + // Backup the scope + var/datum/scope/globalScope = interpreter.globalScope + var/datum/scope/curScope = interpreter.curScope + var/list/scopes = interpreter.scopes.stack.Copy() + var/list/functions = interpreter.functions.stack.Copy() + var/datum/node/statement/FunctionDefinition/curFunction = interpreter.curFunction + var/status = interpreter.status + var/returnVal = interpreter.returnVal + // Sleep + sleep(time) + // Restore the scope + interpreter.returnVal = returnVal + interpreter.status = status + interpreter.curFunction = curFunction + interpreter.functions.stack = functions + interpreter.scopes.stack = scopes + interpreter.curScope = curScope + interpreter.globalScope = globalScope + /datum/signal/proc/mem(var/address, var/value) if(istext(address)) var/obj/machinery/telecomms/server/S = data["server"] diff --git a/code/modules/scripting/Implementations/_Logic.dm b/code/modules/scripting/Implementations/_Logic.dm index 6befaa6f0eb..c31d55f3077 100644 --- a/code/modules/scripting/Implementations/_Logic.dm +++ b/code/modules/scripting/Implementations/_Logic.dm @@ -99,11 +99,6 @@ // --- Miscellaneous functions --- -// Clone of sleep() -/proc/delay(var/time) - //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/delay() called tick#: [world.time]") - sleep(time) - // Clone of rand() /proc/rand_chance(var/low = 0, var/high) //writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/rand_chance() called tick#: [world.time]") diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 2a794de2ff8..119378d53f4 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -683,7 +683,12 @@ to_chat(usr, "Access denied.") return + var/list/options = params2list(possible_destinations) if(href_list["move"]) + if(!options.Find(href_list["move"])) //I see you're trying Href exploits, I see you're failing, I SEE ADMIN WARNING. + // Seriously, though, NEVER trust a Topic with something like this. Ever. + message_admins("move HREF ([src] attempted to move to: [href_list["move"]]) exploit attempted by [key_name_admin(usr)] on [src] (JMP)") + return switch(shuttle_master.moveShuttle(shuttleId, href_list["move"], 1)) if(0) to_chat(usr, "Shuttle received message and will be sent shortly.") diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm index 3386f4b9366..90f2d9afed0 100644 --- a/code/modules/surgery/limb_reattach.dm +++ b/code/modules/surgery/limb_reattach.dm @@ -97,10 +97,12 @@ E.forceMove(target) if(target.get_species() == "Machine")//as this is the only step needed for ipc put togethers if(target_zone == "head") - var/obj/item/organ/external/head/H = target.organs_by_name["head"] + var/obj/item/organ/external/head/H = target.get_organ("head") var/datum/robolimb/robohead = all_robolimbs[H.model] if(robohead.is_monitor) //Ensures that if an IPC gets a head that's got a human hair wig attached to their body, the hair won't wipe. - target.h_style = "" + H.h_style = "" + H.f_style = "" + target.m_style = "" E.status &= ~ORGAN_DESTROYED if(E.children) for(var/obj/item/organ/external/C in E.children) diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index f2dd4c3c778..c1a1c7562a9 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -190,7 +190,9 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 if(src.species.exotic_blood) vessel.remove_reagent(species.exotic_blood,amm) - vessel.reaction(T, TOUCH, amm) + if(vessel.total_volume) + var/fraction = amm / vessel.total_volume + vessel.reaction(T, TOUCH, fraction) return else diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index db6ffd81a2a..0488d768adf 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -54,6 +54,7 @@ var/global/list/limb_icon_cache = list() overlays.Cut() if(!owner) return + var/obj/item/organ/external/head/H = owner.get_organ("head") if(species.has_organ["eyes"]) var/obj/item/organ/internal/eyes/eyes = owner.get_int_organ(/obj/item/organ/internal/eyes)//owner.internal_organs_by_name["eyes"] @@ -79,32 +80,32 @@ var/global/list/limb_icon_cache = list() markings_s.Blend(rgb(owner.r_markings, owner.g_markings, owner.b_markings), ICON_ADD) overlays |= markings_s - if(owner.ha_style) - var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[owner.ha_style] - if(head_accessory_style && head_accessory_style.species_allowed && (species.name in head_accessory_style.species_allowed)) + if(H.ha_style) + var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[H.ha_style] + if(head_accessory_style && head_accessory_style.species_allowed && (H.species.name in head_accessory_style.species_allowed)) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") if(head_accessory_style.do_colouration) - head_accessory_s.Blend(rgb(owner.r_headacc, owner.g_headacc, owner.b_headacc), ICON_ADD) + head_accessory_s.Blend(rgb(H.r_headacc, H.g_headacc, H.b_headacc), ICON_ADD) overlays |= head_accessory_s - if(owner.f_style) - var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style] - if(facial_hair_style && ((facial_hair_style.species_allowed && (species.name in facial_hair_style.species_allowed)) || (src.species.flags & ALL_RPARTS))) + if(H.f_style) + var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[H.f_style] + if(facial_hair_style && ((facial_hair_style.species_allowed && (H.species.name in facial_hair_style.species_allowed)) || (src.species.flags & ALL_RPARTS))) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(species.name == "Slime People") // I am el worstos + if(H.species.name == "Slime People") // I am el worstos facial_s.Blend(rgb(owner.r_skin, owner.g_skin, owner.b_skin, 160), ICON_AND) else if(facial_hair_style.do_colouration) - facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD) + facial_s.Blend(rgb(H.r_facial, H.g_facial, H.b_facial), ICON_ADD) overlays |= facial_s - if(owner.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) - var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style] - if(hair_style && ((species.name in hair_style.species_allowed) || (src.species.flags & ALL_RPARTS))) + if(H.h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) + var/datum/sprite_accessory/hair_style = hair_styles_list[H.h_style] + if(hair_style && ((H.species.name in hair_style.species_allowed) || (src.species.flags & ALL_RPARTS))) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(species.name == "Slime People") // I am el worstos + if(H.species.name == "Slime People") // I am el worstos hair_s.Blend(rgb(owner.r_skin, owner.g_skin, owner.b_skin, 160), ICON_AND) else if(hair_style.do_colouration) - hair_s.Blend(rgb(owner.r_hair, owner.g_hair, owner.b_hair), ICON_ADD) + hair_s.Blend(rgb(H.r_hair, H.g_hair, H.b_hair), ICON_ADD) overlays |= hair_s return mob_icon diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 248da9d1154..8c80b58519a 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -499,18 +499,19 @@ if(istype(owner, /mob/living/carbon/human)) var/mob/living/carbon/human/H = owner - if(!(H.h_style == "Very Long Hair" || H.h_style == "Mowhawk")) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + if(!(head_organ.h_style == "Very Long Hair" || head_organ.h_style == "Mohawk")) if(prob(10)) - H.h_style = "Mohawk" + head_organ.h_style = "Mohawk" else - H.h_style = "Very Long Hair" - H.r_hair = 216 - H.g_hair = 192 - H.b_hair = 120 + head_organ.h_style = "Very Long Hair" + head_organ.r_hair = 216 + head_organ.g_hair = 192 + head_organ.b_hair = 120 H.update_hair() - if(!(H.f_style == "Very Long Beard")) - H.f_style = "Very Long Beard" - H.r_facial = 216 - H.g_facial = 192 - H.b_facial = 120 + if(!(head_organ.f_style == "Very Long Beard")) + head_organ.f_style = "Very Long Beard" + head_organ.r_facial = 216 + head_organ.g_facial = 192 + head_organ.b_facial = 120 H.update_fhair() \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm index c9cbbb17906..d481ba1b7ae 100644 --- a/code/modules/surgery/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -141,6 +141,24 @@ encased = "skull" var/can_intake_reagents = 1 + //Hair colour and style + var/r_hair = 0 + var/g_hair = 0 + var/b_hair = 0 + var/h_style = "Bald" + + //Head accessory colour and style + var/r_headacc = 0 + var/g_headacc = 0 + var/b_headacc = 0 + var/ha_style = "None" + + //Facial hair colour and style + var/r_facial = 0 + var/g_facial = 0 + var/b_facial = 0 + var/f_style = "Shaved" + /obj/item/organ/external/head/remove() if(owner) if(!istype(dna)) diff --git a/config/example/game_options.txt b/config/example/game_options.txt index 69847e0a6b6..5d82bfb425d 100644 --- a/config/example/game_options.txt +++ b/config/example/game_options.txt @@ -54,6 +54,10 @@ ANIMAL_DELAY 0 ## Uncomment for explosions that react to doors and walls REACTIONARY_EXPLOSIONS +# The number of objectives traitors get. +# Not including escaping/hijacking. +TRAITOR_OBJECTIVES_AMOUNT 2 + ### Configure the bomb cap ## This caps all explosions to the specified range. Used for both balance reasons and to prevent overloading the server and lagging the game out. ## This is given as the 3rd number(light damage) in the standard (1,2,3) explosion notation. The other numbers are derived by dividing by 2 and 4. diff --git a/html/changelogs/AutoChangeLog-pr-4231.yml b/html/changelogs/AutoChangeLog-pr-4231.yml new file mode 100644 index 00000000000..047c22c3b30 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4231.yml @@ -0,0 +1,4 @@ +author: monster860 +delete-after: True +changes: + - bugfix: "Fixes sleep() in telecomms" diff --git a/html/changelogs/AutoChangeLog-pr-4331.yml b/html/changelogs/AutoChangeLog-pr-4331.yml new file mode 100644 index 00000000000..f6ca1298944 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4331.yml @@ -0,0 +1,14 @@ +author: KasparoVy +delete-after: True +changes: + - tweak: "Refactors hair so it's on the head (organ)." + - tweak: "Adjusts some Vox hair style names so they're consistent with all others." + - tweak: "Refactors Morph and the order by which options are presented." + - tweak: "Players with heads of a different species than the body will now only be able to access the head accessories, hair/facial hair styles of the head's species." + - bugfix: "Fixes some typos." + - bugfix: "Fixes a bug where hairgrownium made you bald and super hairgrownium only changed the hair/facial hair styles of Humans." + - bugfix: "Fixes a bug where Morph wouldn't correctly set eye colour or skin tone." + - bugfix: "Fixes a typo that didn't really have any negative effect on the beard organ to begin with." + - bugfix: "Fixes bugs where Alopecia and Facial Hypertrichosis disease symptoms wouldn't update player sprite correctly." + - rscadd: "Adds a new Vox hairstyle." + - rscadd: "You can now change your head accessory (and its colour), body markings (and their colour), and body accessory if you're a species that has such things via the Morph genetic power and C.M.A. (the bathroom SalonPro Nano-Mirrors and admin verbs)." diff --git a/html/changelogs/AutoChangeLog-pr-4375.yml b/html/changelogs/AutoChangeLog-pr-4375.yml new file mode 100644 index 00000000000..5556d1b71b2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4375.yml @@ -0,0 +1,4 @@ +author: monster860 +delete-after: True +changes: + - rscadd: "Windows can now be constructed and deconstructed using RCD's." diff --git a/html/changelogs/AutoChangeLog-pr-4391.yml b/html/changelogs/AutoChangeLog-pr-4391.yml new file mode 100644 index 00000000000..8567b77dbee --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4391.yml @@ -0,0 +1,6 @@ +author: Fox MCCloud +delete-after: True +changes: + - tweak: "Removes \"harm\" traitor objective" + - tweak: "Increases non-escape/hijack/die objectives from 1 to 2" + - tweak: "Tweaks available objectives to traitors a bit" diff --git a/html/changelogs/AutoChangeLog-pr-4401.yml b/html/changelogs/AutoChangeLog-pr-4401.yml new file mode 100644 index 00000000000..8f9a142b383 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4401.yml @@ -0,0 +1,4 @@ +author: Fox McCloud +delete-after: True +changes: + - tweak: "Players can no longer see how many players have readied up or who has readied up" diff --git a/html/changelogs/AutoChangeLog-pr-4407.yml b/html/changelogs/AutoChangeLog-pr-4407.yml new file mode 100644 index 00000000000..936843c7952 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4407.yml @@ -0,0 +1,4 @@ +author: Fox McCloud +delete-after: True +changes: + - tweak: "Hulks, Shadowlings, and Golems can no longer use laserpointers" diff --git a/html/changelogs/AutoChangeLog-pr-4415.yml b/html/changelogs/AutoChangeLog-pr-4415.yml new file mode 100644 index 00000000000..25ae9a07845 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4415.yml @@ -0,0 +1,4 @@ +author: Fox McCloud +delete-after: True +changes: + - rscadd: "Adds in the ability to flip over someone with *flip" diff --git a/html/changelogs/AutoChangeLog-pr-4423.yml b/html/changelogs/AutoChangeLog-pr-4423.yml new file mode 100644 index 00000000000..c59bf34afcb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4423.yml @@ -0,0 +1,4 @@ +author: Fox McCloud +delete-after: True +changes: + - tweak: "Fixes and improves foam to better interact with reagents" diff --git a/html/changelogs/AutoChangeLog-pr-4427.yml b/html/changelogs/AutoChangeLog-pr-4427.yml new file mode 100644 index 00000000000..fdec7855212 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4427.yml @@ -0,0 +1,4 @@ +author: AugRob +delete-after: True +changes: + - rscadd: "Add screwdriver sound when opening/closing panels on airlocks" diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index f036d7e3111..a53d468804d 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl index 19e7fd4759b..886076f21d2 100644 --- a/nano/templates/appearance_changer.tmpl +++ b/nano/templates/appearance_changer.tmpl @@ -23,7 +23,7 @@ {{/if}} -{{if data.change_eye_color || data.change_skin_tone || data.change_skin_color || data.change_hair_color || data.change_facial_hair_color}} +{{if data.change_eye_color || data.change_skin_tone || data.change_skin_color || data.change_head_accessory_color || data.change_hair_color || data.change_facial_hair_color || data.change_marking_color}}
Colors: @@ -38,12 +38,31 @@ {{if data.change_skin_color}} {{:helper.link('Change skin color', null, { 'skin_color' : 1})}} {{/if}} + {{if data.change_head_accessory_color}} + {{:helper.link('Change head accessory color', null, { 'head_accessory_color' : 1})}} + {{/if}} {{if data.change_hair_color}} {{:helper.link('Change hair color', null, { 'hair_color' : 1})}} {{/if}} {{if data.change_facial_hair_color}} {{:helper.link('Change facial hair color', null, { 'facial_hair_color' : 1})}} {{/if}} + {{if data.change_marking_color}} + {{:helper.link('Change marking color', null, { 'marking_color' : 1})}} + {{/if}} +
+
+{{/if}} + +{{if data.change_head_accessory}} +
+
+ Head accessory styles: +
+
+ {{for data.head_accessory_styles}} + {{:helper.link(value.headaccessorystyle, null, { 'head_accessory' : value.headaccessorystyle}, null, data.head_accessory_style == value.headaccessorystyle ? 'selected' : null)}} + {{/for}}
{{/if}} @@ -73,3 +92,29 @@ {{/if}} + +{{if data.change_markings}} +
+
+ Marking styles: +
+
+ {{for data.marking_styles}} + {{:helper.link(value.markingstyle, null, { 'marking' : value.markingstyle}, null, data.marking_style == value.markingstyle ? 'selected' : null)}} + {{/for}} +
+
+{{/if}} + +{{if data.change_body_accessory}} +
+
+ Body accessory styles: +
+
+ {{for data.body_accessory_styles}} + {{:helper.link(value.bodyaccessorystyle, null, { 'body_accessory' : value.bodyaccessorystyle}, null, data.body_accessory_style == value.bodyaccessorystyle ? 'selected' : null)}} + {{/for}} +
+
+{{/if}}