From b2cf723067e54cca6848b1d63b92a8cdf19297c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Nov 2020 03:56:55 +0000 Subject: [PATCH 01/22] Bump pillow from 5.1.0 to 7.1.0 in /tools/mapmerge2 Bumps [pillow](https://github.com/python-pillow/Pillow) from 5.1.0 to 7.1.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/master/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/5.1.0...7.1.0) Signed-off-by: dependabot[bot] --- tools/mapmerge2/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mapmerge2/requirements.txt b/tools/mapmerge2/requirements.txt index adb42438..fb643971 100644 --- a/tools/mapmerge2/requirements.txt +++ b/tools/mapmerge2/requirements.txt @@ -1,3 +1,3 @@ pygit2==0.27.2 bidict==0.13.1 -Pillow==5.1.0 +Pillow==7.1.0 From d29b0b75b000a7e1acdd42c969964d6ca7db14e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Nov 2020 03:57:11 +0000 Subject: [PATCH 02/22] Bump bl from 1.2.2 to 1.2.3 in /tgui Bumps [bl](https://github.com/rvagg/bl) from 1.2.2 to 1.2.3. - [Release notes](https://github.com/rvagg/bl/releases) - [Commits](https://github.com/rvagg/bl/compare/v1.2.2...v1.2.3) Signed-off-by: dependabot[bot] --- tgui/package-lock.json | 86 +++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/tgui/package-lock.json b/tgui/package-lock.json index ccc10010..db08e572 100644 --- a/tgui/package-lock.json +++ b/tgui/package-lock.json @@ -1035,9 +1035,9 @@ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=" }, "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" @@ -1540,6 +1540,15 @@ "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==" }, + "call-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", + "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + } + }, "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", @@ -2379,9 +2388,9 @@ }, "dependencies": { "type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", - "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" } } }, @@ -2450,6 +2459,11 @@ "time-stamp": "^1.0.0" } }, + "fast-levenshtein": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", + "integrity": "sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk=" + }, "fg-loadcss": { "version": "1.0.0-0", "resolved": "https://registry.npmjs.org/fg-loadcss/-/fg-loadcss-1.0.0-0.tgz", @@ -3361,6 +3375,26 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, + "get-intrinsic": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", + "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "dependencies": { + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + } + } + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -5441,14 +5475,21 @@ } }, "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + } } }, "object.defaults": { @@ -7512,15 +7553,16 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" }, "undertaker": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", - "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", + "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", "requires": { "arr-flatten": "^1.0.1", "arr-map": "^2.0.0", "bach": "^1.0.0", "collection-map": "^1.0.0", "es6-weak-map": "^2.0.1", + "fast-levenshtein": "^1.0.0", "last-run": "^1.1.0", "object.defaults": "^1.0.0", "object.reduce": "^1.0.0", @@ -7761,9 +7803,9 @@ "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==" }, "vinyl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", - "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", "requires": { "clone": "^2.1.1", "clone-buffer": "^1.0.0", @@ -7844,9 +7886,9 @@ "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==" }, "vinyl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", - "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", "requires": { "clone": "^2.1.1", "clone-buffer": "^1.0.0", From 752a3d9bccfd1948cc491c6954ba2cf2a793495a Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Mon, 7 Oct 2019 23:36:11 -0700 Subject: [PATCH 03/22] Merge pull request #9418 from Ghommie/Ghommie-cit216 Porting a load of viro, (sentient) disease, symptoms code updates from tg. --- code/__DEFINES/logging.dm | 1 + code/__DEFINES/traits.dm | 1 + code/__HELPERS/_logging.dm | 4 + code/_globalvars/logging.dm | 2 + .../configuration/entries/general.dm | 2 + code/datums/components/storage/storage.dm | 2 +- code/datums/diseases/_MobProcs.dm | 6 + code/datums/diseases/_disease.dm | 13 +- code/datums/diseases/advance/advance.dm | 48 ++- .../datums/diseases/advance/symptoms/cough.dm | 2 +- code/datums/diseases/advance/symptoms/heal.dm | 18 ++ .../diseases/advance/symptoms/oxygen.dm | 16 + .../diseases/advance/symptoms/sneeze.dm | 3 +- .../diseases/advance/symptoms/species.dm | 16 +- .../diseases/advance/symptoms/symptoms.dm | 14 +- code/game/objects/items/devices/flashlight.dm | 2 +- code/game/world.dm | 1 + .../antagonists/disease/disease_abilities.dm | 301 +++++++++++------- .../antagonists/disease/disease_disease.dm | 1 + .../antagonists/disease/disease_mob.dm | 31 +- code/modules/mob/camera/camera.dm | 3 + code/modules/mob/dead/dead.dm | 3 + code/modules/mob/living/living.dm | 5 + code/modules/mob/mob.dm | 3 + .../reagents/chemistry/machinery/pandemic.dm | 2 + config/config.txt | 3 + 26 files changed, 357 insertions(+), 146 deletions(-) diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index 8548b2be..6549dd75 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -35,6 +35,7 @@ #define LOG_GAME (1 << 12) #define LOG_ADMIN_PRIVATE (1 << 13) #define LOG_ASAY (1 << 14) +#define LOG_VIRUS (1 << 15) //Individual logging panel pages #define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 657cfdae..a38aaeaa 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -184,6 +184,7 @@ #define OBESITY "obesity" #define MAGIC_TRAIT "magic" #define TRAUMA_TRAIT "trauma" +#define DISEASE_TRAIT "disease" #define SPECIES_TRAIT "species" #define ORGAN_TRAIT "organ" #define JOB_TRAIT "job" diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 8deb1f9f..774b8768 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -61,6 +61,10 @@ if (CONFIG_GET(flag/log_game)) WRITE_LOG(GLOB.world_game_log, "GAME: [text]") +/proc/log_virus(text) + if (CONFIG_GET(flag/log_virus)) + WRITE_LOG(GLOB.world_virus_log, "VIRUS: [text]") + /proc/log_access(text) if (CONFIG_GET(flag/log_access)) WRITE_LOG(GLOB.world_game_log, "ACCESS: [text]") diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index deffd25b..485e67e2 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -26,6 +26,8 @@ GLOBAL_VAR(query_debug_log) GLOBAL_PROTECT(query_debug_log) GLOBAL_VAR(world_job_debug_log) GLOBAL_PROTECT(world_job_debug_log) +GLOBAL_VAR(world_virus_log) +GLOBAL_PROTECT(world_virus_log) GLOBAL_LIST_EMPTY(bombers) GLOBAL_PROTECT(bombers) diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index ceb879d5..03d52cd9 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -39,6 +39,8 @@ /datum/config_entry/flag/log_game // log game events +/datum/config_entry/flag/log_virus // log virology data + /datum/config_entry/flag/log_vote // log voting /datum/config_entry/flag/log_whisper // log client whisper diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 98af707e..8a58f112 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -234,7 +234,7 @@ /datum/component/storage/proc/quick_empty(mob/M) var/atom/A = parent - if((!ishuman(M) && (A.loc != M)) || (M.stat != CONSCIOUS) || M.restrained() || !M.canmove) + if(!M.canUseStorage() || !A.Adjacent(M) || M.incapacitated()) return if(check_locked(null, M, TRUE)) return FALSE diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index e1432bf9..c125a9b7 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -144,3 +144,9 @@ if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs))) return FALSE return ..() + +/mob/living/proc/CanSpreadAirborneDisease() + return !is_mouth_covered() + +/mob/living/carbon/CanSpreadAirborneDisease() + return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating("bio") >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating("bio") >= 25))) \ No newline at end of file diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 0af4eea8..8a696666 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -55,6 +55,13 @@ D.after_add() infectee.med_hud_set_status() + var/turf/source_turf = get_turf(infectee) + log_virus("[key_name(infectee)] was infected by virus: [src.admin_details()] at [loc_name(source_turf)]") + +//Return a string for admin logging uses, should describe the disease in detail +/datum/disease/proc/admin_details() + return "[src.name] : [src.type]" + /datum/disease/proc/stage_act() var/cure = has_cure() @@ -65,15 +72,17 @@ if(!cure) if(prob(stage_prob)) - stage = min(stage + 1,max_stages) + update_stage(min(stage + 1,max_stages)) else if(prob(cure_chance)) - stage = max(stage - 1, 1) + update_stage(max(stage - 1, 1)) if(disease_flags & CURABLE) if(cure && prob(cure_chance)) cure() +/datum/disease/proc/update_stage(new_stage) + stage = new_stage /datum/disease/proc/has_cure() if(!(disease_flags & CURABLE)) diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 6a41b710..b70f44fd 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -31,9 +31,9 @@ var/id = "" var/processing = FALSE var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology - var/oldres + var/oldres //To prevent setting new cures unless resistance changes. - // The order goes from easy to cure to hard to cure. + // The order goes from easy to cure to hard to cure. Keep in mind that sentient diseases pick two cures from tier 6 and up, ensure they wont react away in bodies. var/static/list/advance_cures = list( list( // level 1 "copper", "silver", "iodine", "iron", "carbon" @@ -110,15 +110,22 @@ return if(symptoms && symptoms.len) - if(!processing) processing = TRUE for(var/datum/symptom/S in symptoms) - S.Start(src) + if(S.Start(src)) //this will return FALSE if the symptom is neutered + S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10) + S.on_stage_change(src) for(var/datum/symptom/S in symptoms) S.Activate(src) +// Tell symptoms stage changed +/datum/disease/advance/update_stage(new_stage) + ..() + for(var/datum/symptom/S in symptoms) + S.on_stage_change(src) + // Compares type then ID. /datum/disease/advance/IsSame(datum/disease/advance/D) @@ -137,10 +144,16 @@ A.symptoms += S.Copy() A.properties = properties.Copy() A.id = id - A.mutable = mutable + A.oldres = oldres //this is a new disease starting over at stage 1, so processing is not copied return A +//Describe this disease to an admin in detail (for logging) +/datum/disease/advance/admin_details() + var/list/name_symptoms = list() + for(var/datum/symptom/S in symptoms) + name_symptoms += S.name + return "[name] sym:[english_list(name_symptoms)] r:[totalResistance()] s:[totalStealth()] ss:[totalStageSpeed()] t:[totalTransmittable()]" /* NEW PROCS @@ -191,6 +204,10 @@ /datum/disease/advance/proc/Refresh(new_name = FALSE) GenerateProperties() AssignProperties() + if(processing && symptoms && symptoms.len) + for(var/datum/symptom/S in symptoms) + S.Start(src) + S.on_stage_change(src) id = null var/the_id = GetDiseaseID() @@ -342,28 +359,28 @@ return id -// Add a symptom, if it is over the limit (with a small chance to be able to go over) -// we take a random symptom away and add the new one. +// Add a symptom, if it is over the limit we take a random symptom away and add the new one. /datum/disease/advance/proc/AddSymptom(datum/symptom/S) if(HasSymptom(S)) return - if(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1)) - symptoms += S - else + if(!(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1))) RemoveSymptom(pick(symptoms)) - symptoms += S + symptoms += S + S.OnAdd(src) // Simply removes the symptom. /datum/disease/advance/proc/RemoveSymptom(datum/symptom/S) symptoms -= S + S.OnRemove(src) // Neuter a symptom, so it will only affect stats /datum/disease/advance/proc/NeuterSymptom(datum/symptom/S) if(!S.neutered) S.neutered = TRUE S.name += " (neutered)" + S.OnRemove(src) /* @@ -417,7 +434,7 @@ var/i = VIRUS_SYMPTOM_LIMIT - var/datum/disease/advance/D = new(0, null) + var/datum/disease/advance/D = new() D.symptoms = list() var/list/symptoms = list() @@ -444,10 +461,6 @@ return D.AssignName(new_name) D.Refresh() - - for(var/datum/disease/advance/AD in SSdisease.active_diseases) - AD.Refresh() - for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) if(!is_station_level(H.z)) continue @@ -458,7 +471,8 @@ var/list/name_symptoms = list() for(var/datum/symptom/S in D.symptoms) name_symptoms += S.name - message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]") + message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.admin_details()]") + log_virus("[key_name(user)] has triggered a custom virus outbreak of [D.admin_details()]!") /datum/disease/advance/proc/totalStageSpeed() diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm index 23c332ec..b1767d7c 100644 --- a/code/datums/diseases/advance/symptoms/cough.dm +++ b/code/datums/diseases/advance/symptoms/cough.dm @@ -70,6 +70,6 @@ BONUS addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 6) addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 12) addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 18) - if(infective) + if(infective && M.CanSpreadAirborneDisease()) A.spread(1) diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index e666c7ac..1ab3456c 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -219,8 +219,10 @@ level = 8 passive_message = "The pain from your wounds makes you feel oddly sleepy..." var/deathgasp = FALSE + var/stabilize = FALSE var/active_coma = FALSE //to prevent multiple coma procs threshold_desc = "Stealth 2: Host appears to die when falling into a coma.
\ + Resistance 4: The virus also stabilizes the host while they are in critical condition.
\ Stage Speed 7: Increases healing speed." /datum/symptom/heal/coma/Start(datum/disease/advance/A) @@ -228,9 +230,25 @@ return if(A.properties["stage_rate"] >= 7) power = 1.5 + if(A.properties["resistance"] >= 4) + stabilize = TRUE if(A.properties["stealth"] >= 2) deathgasp = TRUE +/datum/symptom/heal/coma/on_stage_change(datum/disease/advance/A) //mostly copy+pasted from the code for self-respiration's TRAIT_NOBREATH stuff + if(!..()) + return FALSE + if(A.stage >= 4 && stabilize) + ADD_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT) + else + REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT) + return TRUE + +/datum/symptom/heal/coma/End(datum/disease/advance/A) + if(!..()) + return + REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT) + /datum/symptom/heal/coma/CanHeal(datum/disease/advance/A) var/mob/living/M = A.affected_mob if(HAS_TRAIT(M, TRAIT_DEATHCOMA)) diff --git a/code/datums/diseases/advance/symptoms/oxygen.dm b/code/datums/diseases/advance/symptoms/oxygen.dm index cb7d1a6d..65f83071 100644 --- a/code/datums/diseases/advance/symptoms/oxygen.dm +++ b/code/datums/diseases/advance/symptoms/oxygen.dm @@ -50,3 +50,19 @@ Bonus if(prob(base_message_chance)) to_chat(M, "[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]") return + +/datum/symptom/oxygen/on_stage_change(datum/disease/advance/A) + if(!..()) + return FALSE + var/mob/living/carbon/M = A.affected_mob + if(A.stage >= 4) + ADD_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT) + else + REMOVE_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT) + return TRUE + +/datum/symptom/oxygen/End(datum/disease/advance/A) + if(!..()) + return + if(A.stage >= 4) + REMOVE_TRAIT(A.affected_mob, TRAIT_NOBREATH, DISEASE_TRAIT) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm index 8fe70c54..5e21fb3d 100644 --- a/code/datums/diseases/advance/symptoms/sneeze.dm +++ b/code/datums/diseases/advance/symptoms/sneeze.dm @@ -48,4 +48,5 @@ Bonus M.emote("sniff") else M.emote("sneeze") - A.spread(4 + power) \ No newline at end of file + if(M.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth + A.spread(4 + power) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/species.dm b/code/datums/diseases/advance/symptoms/species.dm index b609529a..1e3df649 100644 --- a/code/datums/diseases/advance/symptoms/species.dm +++ b/code/datums/diseases/advance/symptoms/species.dm @@ -8,12 +8,14 @@ level = 5 severity = 0 -/datum/symptom/undead_adaptation/Start(datum/disease/advance/A) - if(!..()) - return +/datum/symptom/undead_adaptation/OnAdd(datum/disease/advance/A) A.process_dead = TRUE A.infectable_biotypes |= MOB_UNDEAD +/datum/symptom/undead_adaptation/OnRemove(datum/disease/advance/A) + A.process_dead = FALSE + A.infectable_biotypes -= MOB_UNDEAD + /datum/symptom/inorganic_adaptation name = "Inorganic Biology" desc = "The virus can survive and replicate even in an inorganic environment, increasing its resistance and infection rate." @@ -24,8 +26,8 @@ level = 5 severity = 0 -/datum/symptom/inorganic_adaptation/Start(datum/disease/advance/A) - if(!..()) - return +/datum/symptom/inorganic_adaptation/OnAdd(datum/disease/advance/A) A.infectable_biotypes |= MOB_INORGANIC - \ No newline at end of file + +/datum/symptom/inorganic_adaptation/OnRemove(datum/disease/advance/A) + A.infectable_biotypes -= MOB_INORGANIC diff --git a/code/datums/diseases/advance/symptoms/symptoms.dm b/code/datums/diseases/advance/symptoms/symptoms.dm index 04fbf334..76bce9d7 100644 --- a/code/datums/diseases/advance/symptoms/symptoms.dm +++ b/code/datums/diseases/advance/symptoms/symptoms.dm @@ -38,11 +38,10 @@ return CRASH("We couldn't assign an ID!") -// Called when processing of the advance disease, which holds this symptom, starts. +// Called when processing of the advance disease that holds this symptom infects a host and upon each Refresh() of that advance disease. /datum/symptom/proc/Start(datum/disease/advance/A) if(neutered) return FALSE - next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) //so it doesn't instantly activate on infection return TRUE // Called when the advance disease is going to be deleted or when the advance disease stops processing. @@ -60,6 +59,11 @@ next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) return TRUE +/datum/symptom/proc/on_stage_change(datum/disease/advance/A) + if(neutered) + return FALSE + return TRUE + /datum/symptom/proc/Copy() var/datum/symptom/new_symp = new type new_symp.name = name @@ -69,3 +73,9 @@ /datum/symptom/proc/generate_threshold_desc() return + +/datum/symptom/proc/OnAdd(datum/disease/advance/A) //Overload when a symptom needs to be active before processing, like changing biotypes. + return + +/datum/symptom/proc/OnRemove(datum/disease/advance/A) //But dont forget to remove them too. + return diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 13b24b23..5eea5703 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -96,7 +96,7 @@ if(BODY_ZONE_PRECISE_MOUTH) - if((M.head && M.head.flags_cover & HEADCOVERSMOUTH) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH)) + if(M.is_mouth_covered()) to_chat(user, "You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSMOUTH) ? "helmet" : "mask"] first.") return diff --git a/code/game/world.dm b/code/game/world.dm index 3d01218b..64ebce37 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -107,6 +107,7 @@ GLOBAL_VAR(restart_counter) GLOB.picture_log_directory = "data/picture_logs/[override_dir]" GLOB.world_game_log = "[GLOB.log_directory]/game.log" + GLOB.world_virus_log = "[GLOB.log_directory]/virus.log" GLOB.world_attack_log = "[GLOB.log_directory]/attack.log" GLOB.world_pda_log = "[GLOB.log_directory]/pda.log" GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log" diff --git a/code/modules/antagonists/disease/disease_abilities.dm b/code/modules/antagonists/disease/disease_abilities.dm index 77e0e976..dc224900 100644 --- a/code/modules/antagonists/disease/disease_abilities.dm +++ b/code/modules/antagonists/disease/disease_abilities.dm @@ -5,25 +5,48 @@ is currently following. */ GLOBAL_LIST_INIT(disease_ability_singletons, list( - new /datum/disease_ability/action/cough(), - new /datum/disease_ability/action/sneeze(), - new /datum/disease_ability/action/infect(), - new /datum/disease_ability/symptom/cough(), - new /datum/disease_ability/symptom/sneeze(),\ - new /datum/disease_ability/symptom/hallucigen(), - new /datum/disease_ability/symptom/choking(), - new /datum/disease_ability/symptom/confusion(), - new /datum/disease_ability/symptom/youth(), - new /datum/disease_ability/symptom/vomit(), - new /datum/disease_ability/symptom/voice_change(), - new /datum/disease_ability/symptom/visionloss(), - new /datum/disease_ability/symptom/viraladaptation(), - new /datum/disease_ability/symptom/vitiligo(), - new /datum/disease_ability/symptom/sensory_restoration(), - new /datum/disease_ability/symptom/itching(), - new /datum/disease_ability/symptom/weight_loss(), - new /datum/disease_ability/symptom/metabolism_heal(), - new /datum/disease_ability/symptom/coma_heal() + new /datum/disease_ability/action/cough, + new /datum/disease_ability/action/sneeze, + new /datum/disease_ability/action/infect, + new /datum/disease_ability/symptom/mild/cough, + new /datum/disease_ability/symptom/mild/sneeze, + new /datum/disease_ability/symptom/medium/shedding, + new /datum/disease_ability/symptom/medium/beard, + new /datum/disease_ability/symptom/medium/hallucigen, + new /datum/disease_ability/symptom/medium/choking, + new /datum/disease_ability/symptom/medium/confusion, + new /datum/disease_ability/symptom/medium/vomit, + new /datum/disease_ability/symptom/medium/voice_change, + new /datum/disease_ability/symptom/medium/visionloss, + new /datum/disease_ability/symptom/medium/deafness, + new /datum/disease_ability/symptom/powerful/narcolepsy, + new /datum/disease_ability/symptom/medium/fever, + new /datum/disease_ability/symptom/medium/shivering, + new /datum/disease_ability/symptom/medium/headache, + new /datum/disease_ability/symptom/medium/nano_boost, + new /datum/disease_ability/symptom/medium/nano_destroy, + new /datum/disease_ability/symptom/medium/viraladaptation, + new /datum/disease_ability/symptom/medium/viralevolution, + new /datum/disease_ability/symptom/medium/vitiligo, + new /datum/disease_ability/symptom/medium/revitiligo, + new /datum/disease_ability/symptom/medium/itching, + new /datum/disease_ability/symptom/medium/heal/weight_loss, + new /datum/disease_ability/symptom/medium/heal/sensory_restoration, + new /datum/disease_ability/symptom/medium/heal/mind_restoration, + new /datum/disease_ability/symptom/powerful/fire, + new /datum/disease_ability/symptom/powerful/flesh_eating, +// new /datum/disease_ability/symptom/powerful/genetic_mutation, + new /datum/disease_ability/symptom/powerful/inorganic_adaptation, + new /datum/disease_ability/symptom/powerful/heal/starlight, + new /datum/disease_ability/symptom/powerful/heal/oxygen, + new /datum/disease_ability/symptom/powerful/heal/chem, + new /datum/disease_ability/symptom/powerful/heal/metabolism, + new /datum/disease_ability/symptom/powerful/heal/dark, + new /datum/disease_ability/symptom/powerful/heal/water, + new /datum/disease_ability/symptom/powerful/heal/plasma, + new /datum/disease_ability/symptom/powerful/heal/radiation, + new /datum/disease_ability/symptom/powerful/heal/coma, + new /datum/disease_ability/symptom/powerful/youth )) /datum/disease_ability @@ -54,7 +77,13 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list( stage_speed += initial(S.stage_speed) transmittable += initial(S.transmittable) threshold_block += "

[initial(S.threshold_desc)]" - stat_block = "Resistance: [resistance]
Stealth: [stealth]
Stage Speed: [stage_speed]
Transmissibility: [transmittable]

" + stat_block = "Resistance: [resistance]
Stealth: [stealth]
Stage Speed: [stage_speed]
Transmissibility: [transmittable]

" + if(symptoms.len == 1) //lazy boy's dream + name = initial(S.name) + if(short_desc == "") + short_desc = initial(S.desc) + if(long_desc == "") + long_desc = initial(S.desc) /datum/disease_ability/proc/CanBuy(mob/camera/disease/D) if(world.time < D.next_adaptation_time) @@ -77,8 +106,10 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list( for(var/T in symptoms) var/datum/symptom/S = new T() SD.symptoms += S + S.OnAdd(SD) if(SD.processing) - S.Start(SD) + if(S.Start(SD)) + S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10) SD.Refresh() for(var/T in actions) var/datum/action/A = new T() @@ -105,6 +136,7 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list( var/datum/symptom/S = locate(T) in SD.symptoms if(S) SD.symptoms -= S + S.OnRemove(SD) if(SD.processing) S.End(SD) qdel(S) @@ -152,8 +184,9 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list( return FALSE to_chat(D, "You force [L.real_name] to cough.") L.emote("cough") - var/datum/disease/advance/sentient_disease/SD = D.hosts[L] - SD.spread(2) + if(L.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth + var/datum/disease/advance/sentient_disease/SD = D.hosts[L] + SD.spread(2) StartCooldown() return TRUE @@ -185,11 +218,12 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list( return FALSE to_chat(D, "You force [L.real_name] to sneeze.") L.emote("sneeze") - var/datum/disease/advance/sentient_disease/SD = D.hosts[L] + if(L.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth + var/datum/disease/advance/sentient_disease/SD = D.hosts[L] - for(var/mob/living/M in oview(4, SD.affected_mob)) - if(is_A_facing_B(SD.affected_mob, M) && disease_air_spread_walk(get_turf(SD.affected_mob), get_turf(M))) - M.AirborneContractDisease(SD, TRUE) + for(var/mob/living/M in oview(4, SD.affected_mob)) + if(is_A_facing_B(SD.affected_mob, M) && disease_air_spread_walk(get_turf(SD.affected_mob), get_turf(M))) + M.AirborneContractDisease(SD, TRUE) StartCooldown() return TRUE @@ -235,143 +269,192 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list( StartCooldown() return TRUE -//passive symptom abilities +/*******************BASE SYMPTOM TYPES*******************/ +// cost is for convenience and can be changed. If you're changing req_tot_points then don't use the subtype... +//healing costs more so you have to techswitch from naughty disease otherwise we'd have friendly disease for easy greentext (no fun!) -/datum/disease_ability/symptom/cough - name = "Involuntary Coughing" - symptoms = list(/datum/symptom/cough) +/datum/disease_ability/symptom/mild cost = 2 required_total_points = 4 + category = "Symptom (Weak)" + +/datum/disease_ability/symptom/medium + cost = 4 + required_total_points = 8 + category = "Symptom" + +/datum/disease_ability/symptom/medium/heal + cost = 5 + category = "Symptom (+)" + +/datum/disease_ability/symptom/powerful + cost = 4 + required_total_points = 16 + category = "Symptom (Strong)" + +/datum/disease_ability/symptom/powerful/heal + cost = 8 + category = "Symptom (Strong+)" + + +/******MILD******/ + +/datum/disease_ability/symptom/mild/cough + name = "Involuntary Coughing" + symptoms = list(/datum/symptom/cough) short_desc = "Cause victims to cough intermittently." long_desc = "Cause victims to cough intermittently, spreading your infection if your transmissibility is high." -/datum/disease_ability/symptom/sneeze +/datum/disease_ability/symptom/mild/sneeze name = "Involuntary Sneezing" symptoms = list(/datum/symptom/sneeze) - cost = 2 - required_total_points = 4 short_desc = "Cause victims to sneeze intermittently." long_desc = "Cause victims to sneeze intermittently, spreading your infection and also increasing transmissibility and resistance, at the cost of stealth." -/datum/disease_ability/symptom/beard - //I don't think I need to justify the fact that this is the best symptom - name = "Beard Growth" - symptoms = list(/datum/symptom/beard) - cost = 1 - required_total_points = 8 - short_desc = "Cause all victims to grow a luscious beard." - long_desc = "Cause all victims to grow a luscious beard. Decreases stats slightly. Ineffective against Santa Claus." +/******MEDIUM******/ -/datum/disease_ability/symptom/hallucigen - name = "Hallucinations" +/datum/disease_ability/symptom/medium/shedding + symptoms = list(/datum/symptom/shedding) + +/datum/disease_ability/symptom/medium/beard + symptoms = list(/datum/symptom/beard) + short_desc = "Cause all victims to grow a luscious beard." + long_desc = "Cause all victims to grow a luscious beard. Ineffective against Santa Claus." + +/datum/disease_ability/symptom/medium/hallucigen symptoms = list(/datum/symptom/hallucigen) - cost = 4 - required_total_points = 8 short_desc = "Cause victims to hallucinate." long_desc = "Cause victims to hallucinate. Decreases stats, especially resistance." -/datum/disease_ability/symptom/choking - name = "Choking" +/datum/disease_ability/symptom/medium/choking symptoms = list(/datum/symptom/choking) - cost = 4 - required_total_points = 8 short_desc = "Cause victims to choke." long_desc = "Cause victims to choke, threatening asphyxiation. Decreases stats, especially transmissibility." - -/datum/disease_ability/symptom/confusion - name = "Confusion" +/datum/disease_ability/symptom/medium/confusion symptoms = list(/datum/symptom/confusion) - cost = 4 - required_total_points = 8 short_desc = "Cause victims to become confused." long_desc = "Cause victims to become confused intermittently." -/datum/disease_ability/symptom/youth - name = "Eternal Youth" - symptoms = list(/datum/symptom/youth) - cost = 4 - required_total_points = 8 - short_desc = "Cause victims to become eternally young." - long_desc = "Cause victims to become eternally young. Provides boosts to all stats except transmissibility." - - -/datum/disease_ability/symptom/vomit - name = "Vomiting" +/datum/disease_ability/symptom/medium/vomit symptoms = list(/datum/symptom/vomit) - cost = 4 - required_total_points = 8 short_desc = "Cause victims to vomit." long_desc = "Cause victims to vomit. Slightly increases transmissibility. Vomiting also also causes the victims to lose nutrition and removes some toxin damage." -/datum/disease_ability/symptom/voice_change - name = "Voice Changing" +/datum/disease_ability/symptom/medium/voice_change symptoms = list(/datum/symptom/voice_change) - cost = 4 - required_total_points = 8 short_desc = "Change the voice of victims." long_desc = "Change the voice of victims, causing confusion in communications." -/datum/disease_ability/symptom/visionloss - name = "Vision Loss" +/datum/disease_ability/symptom/medium/visionloss symptoms = list(/datum/symptom/visionloss) - cost = 4 - required_total_points = 8 short_desc = "Damage the eyes of victims, eventually causing blindness." long_desc = "Damage the eyes of victims, eventually causing blindness. Decreases all stats." -/datum/disease_ability/symptom/viraladaptation - name = "Self-Adaptation" +/datum/disease_ability/symptom/medium/deafness + symptoms = list(/datum/symptom/deafness) + +/datum/disease_ability/symptom/medium/fever + symptoms = list(/datum/symptom/fever) + +/datum/disease_ability/symptom/medium/shivering + symptoms = list(/datum/symptom/shivering) + +/datum/disease_ability/symptom/medium/headache + symptoms = list(/datum/symptom/headache) + +/datum/disease_ability/symptom/medium/nano_boost + symptoms = list(/datum/symptom/nano_boost) + +/datum/disease_ability/symptom/medium/nano_destroy + symptoms = list(/datum/symptom/nano_destroy) + +/datum/disease_ability/symptom/medium/viraladaptation symptoms = list(/datum/symptom/viraladaptation) - cost = 4 - required_total_points = 8 short_desc = "Cause your infection to become more resistant to detection and eradication." long_desc = "Cause your infection to mimic the function of normal body cells, becoming much harder to spot and to eradicate, but reducing its speed." -/datum/disease_ability/symptom/vitiligo - name = "Skin Paleness" +/datum/disease_ability/symptom/medium/viralevolution + symptoms = list(/datum/symptom/viralevolution) + +/datum/disease_ability/symptom/medium/vitiligo symptoms = list(/datum/symptom/vitiligo) - cost = 1 - required_total_points = 8 - short_desc = "Cause victims to become pale." - long_desc = "Cause victims to become pale. Decreases all stats." -/datum/disease_ability/symptom/sensory_restoration - name = "Sensory Restoration" - symptoms = list(/datum/symptom/sensory_restoration) - cost = 4 - required_total_points = 8 - short_desc = "Regenerate eye and ear damage of victims." - long_desc = "Regenerate eye and ear damage of victims." +/datum/disease_ability/symptom/medium/revitiligo + symptoms = list(/datum/symptom/revitiligo) -/datum/disease_ability/symptom/itching - name = "Itching" +/datum/disease_ability/symptom/medium/itching symptoms = list(/datum/symptom/itching) - cost = 4 - required_total_points = 8 short_desc = "Cause victims to itch." long_desc = "Cause victims to itch, increasing all stats except stealth." -/datum/disease_ability/symptom/weight_loss - name = "Weight Loss" +/datum/disease_ability/symptom/medium/heal/weight_loss symptoms = list(/datum/symptom/weight_loss) - cost = 4 - required_total_points = 8 short_desc = "Cause victims to lose weight." long_desc = "Cause victims to lose weight, and make it almost impossible for them to gain nutrition from food. Reduced nutrition allows your infection to spread more easily from hosts, especially by sneezing." -/datum/disease_ability/symptom/metabolism_heal - name = "Metabolic Boost" +/datum/disease_ability/symptom/medium/heal/sensory_restoration + symptoms = list(/datum/symptom/sensory_restoration) + short_desc = "Regenerate eye and ear damage of victims." + long_desc = "Regenerate eye and ear damage of victims." + +/datum/disease_ability/symptom/medium/heal/mind_restoration + symptoms = list(/datum/symptom/mind_restoration) + +/******POWERFUL******/ + +/datum/disease_ability/symptom/powerful/fire + symptoms = list(/datum/symptom/fire) + +/datum/disease_ability/symptom/powerful/flesh_eating + symptoms = list(/datum/symptom/flesh_eating) + +/* +/datum/disease_ability/symptom/powerful/genetic_mutation + symptoms = list(/datum/symptom/genetic_mutation) + cost = 8 +*/ + +/datum/disease_ability/symptom/powerful/inorganic_adaptation + symptoms = list(/datum/symptom/inorganic_adaptation) + +/datum/disease_ability/symptom/powerful/narcolepsy + symptoms = list(/datum/symptom/narcolepsy) + +/datum/disease_ability/symptom/powerful/youth + symptoms = list(/datum/symptom/youth) + short_desc = "Cause victims to become eternally young." + long_desc = "Cause victims to become eternally young. Provides boosts to all stats except transmissibility." + +/****HEALING SUBTYPE****/ + +/datum/disease_ability/symptom/powerful/heal/starlight + symptoms = list(/datum/symptom/heal/starlight) + +/datum/disease_ability/symptom/powerful/heal/oxygen + symptoms = list(/datum/symptom/oxygen) + +/datum/disease_ability/symptom/powerful/heal/chem + symptoms = list(/datum/symptom/heal/chem) + +/datum/disease_ability/symptom/powerful/heal/metabolism symptoms = list(/datum/symptom/heal/metabolism) - cost = 4 - required_total_points = 16 short_desc = "Increase the metabolism of victims, causing them to process chemicals and grow hungry faster." long_desc = "Increase the metabolism of victims, causing them to process chemicals twice as fast and grow hungry more quickly." -/datum/disease_ability/symptom/coma_heal - name = "Regenerative Coma" +/datum/disease_ability/symptom/powerful/heal/dark + symptoms = list(/datum/symptom/heal/darkness) + +/datum/disease_ability/symptom/powerful/heal/water + symptoms = list(/datum/symptom/heal/water) + +/datum/disease_ability/symptom/powerful/heal/plasma + symptoms = list(/datum/symptom/heal/plasma) + +/datum/disease_ability/symptom/powerful/heal/radiation + symptoms = list(/datum/symptom/heal/radiation) + +/datum/disease_ability/symptom/powerful/heal/coma symptoms = list(/datum/symptom/heal/coma) - cost = 8 - required_total_points = 16 short_desc = "Cause victims to fall into a healing coma when hurt." long_desc = "Cause victims to fall into a healing coma when hurt." diff --git a/code/modules/antagonists/disease/disease_disease.dm b/code/modules/antagonists/disease/disease_disease.dm index b4b8ac09..c37abefa 100644 --- a/code/modules/antagonists/disease/disease_disease.dm +++ b/code/modules/antagonists/disease/disease_disease.dm @@ -51,6 +51,7 @@ if(cures.len) return var/list/not_used = advance_cures.Copy() + not_used.Cut(1, 6) // Removes the first five tiers of cures. cures = list(pick(pick_n_take(not_used)), pick(pick_n_take(not_used))) // Get the cure name from the cure_id diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm index 434ecabf..adb448d2 100644 --- a/code/modules/antagonists/disease/disease_mob.dm +++ b/code/modules/antagonists/disease/disease_mob.dm @@ -18,7 +18,7 @@ the new instance inside the host to be updated to the template's stats. layer = BELOW_MOB_LAYER lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE sight = SEE_SELF|SEE_THRU - initial_language_holder = /datum/language_holder/empty + initial_language_holder = /datum/language_holder/universal var/freemove = TRUE var/freemove_end = 0 @@ -43,7 +43,7 @@ the new instance inside the host to be updated to the template's stats. var/move_delay = 1 var/next_adaptation_time = 0 - var/adaptation_cooldown = 1200 + var/adaptation_cooldown = 600 var/list/purchased_abilities var/list/unpurchased_abilities @@ -118,10 +118,28 @@ the new instance inside the host to be updated to the template's stats. follow_next(Dir & NORTHWEST) last_move_tick = world.time +/mob/camera/disease/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) + . = ..() + var/atom/movable/to_follow = speaker + if(radio_freq) + var/atom/movable/virtualspeaker/V = speaker + to_follow = V.source + var/link + if(to_follow in hosts) + link = FOLLOW_LINK(src, to_follow) + else + link = "" + // Recompose the message, because it's scrambled by default + message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode) + to_chat(src, "[link] [message]") + + /mob/camera/disease/mind_initialize() . = ..() if(!mind.has_antag_datum(/datum/antagonist/disease)) mind.add_antag_datum(/datum/antagonist/disease) + var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] + medsensor.add_hud_to(src) /mob/camera/disease/proc/pick_name() var/static/list/taken_names @@ -247,9 +265,12 @@ the new instance inside the host to be updated to the template's stats. if(!move_listener) move_listener = L.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/follow_mob))) else - L.TakeComponent(move_listener) - if(QDELING(move_listener)) - move_listener = null + if(L) + L.TakeComponent(move_listener) + if(QDELING(move_listener)) + move_listener = null + else + QDEL_NULL(move_listener) follow_mob() /mob/camera/disease/proc/follow_next(reverse = FALSE) diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index de4f2c5a..ff1d9231 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -31,5 +31,8 @@ loc = destination Moved(oldloc, NONE, TRUE) +/mob/camera/canUseStorage() + return FALSE + /mob/camera/emote(act, m_type=1, message = null, intentional = FALSE) return diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 288ca6b3..0c50cb04 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -21,6 +21,9 @@ INITIALIZE_IMMEDIATE(/mob/dead) set_focus(src) return INITIALIZE_HINT_NORMAL +/mob/dead/canUseStorage() + return FALSE + /mob/dead/dust(just_ash, drop_items, force) //ghosts can't be vaporised. return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index bd88a3c8..b315428a 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -373,6 +373,11 @@ if(stat || IsUnconscious() || IsStun() || IsKnockdown() || recoveringstam || (!ignore_restraints && restrained(ignore_grab))) // CIT CHANGE - adds recoveringstam check here return TRUE +/mob/living/canUseStorage() + if (get_num_arms() <= 0) + return FALSE + return TRUE + /mob/living/proc/InCritical() return (health <= crit_threshold && (stat == SOFT_CRIT || stat == UNCONSCIOUS)) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c7ce6577..1d14e084 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -830,6 +830,9 @@ /mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE) return +/mob/proc/canUseStorage() + return FALSE + /mob/proc/faction_check_mob(mob/target, exact_match) if(exact_match) //if we need an exact match, we need to do some bullfuckery. var/list/faction_src = faction.Copy() diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index 5e80c42a..e0cbaef6 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -195,6 +195,8 @@ B.reagents.add_reagent("blood", 20, data) wait = TRUE update_icon() + var/turf/source_turf = get_turf(src) + log_virus("A culture bottle was printed for the virus [A.admin_details()] at [loc_name(source_turf)] by [key_name(usr)]") addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50) . = TRUE if("create_vaccine_bottle") diff --git a/config/config.txt b/config/config.txt index d6a6f18f..065af56d 100644 --- a/config/config.txt +++ b/config/config.txt @@ -146,6 +146,9 @@ LOG_MANIFEST ## Enable logging pictures # LOG_PICTURES +## log virus and actions +LOG_VIRUS + ##Log camera pictures - Must have picture logging enabled PICTURE_LOGGING_CAMERA From 2b45cd536d7e9eceed755ec8f7b18f9a905d9a79 Mon Sep 17 00:00:00 2001 From: Dip Date: Tue, 3 Nov 2020 04:37:45 -0300 Subject: [PATCH 04/22] adv hypo design --- code/modules/research/designs/medical_designs.dm | 11 +++++++++++ code/modules/research/techweb/all_nodes.dm | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 2a79d48b..abf7f37a 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -960,3 +960,14 @@ build_path = /obj/item/hypospray/mkii/disposable category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/adv_hypo + name = "Hypospray MK.II" + desc = "A new development from DeForest Medical, this hypospray takes 30-unit vials as the drug supply for easy swapping." + id = "hypo2" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 500) + construction_time = 40 + build_path = /obj/item/hypospray/mkii + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 1d221480..5dee32a5 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -673,7 +673,7 @@ display_name = "Medical Weaponry" description = "Weapons using medical technology." prereq_ids = list("adv_biotech", "adv_weaponry") - design_ids = list("rapidsyringe", "shotgundartcryostatis") + design_ids = list("rapidsyringe", "shotgundartcryostatis", "hypo2") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) export_price = 5000 From 2557084af668a77290037fc984a905bc96e12873 Mon Sep 17 00:00:00 2001 From: Dip Date: Tue, 3 Nov 2020 04:47:55 -0300 Subject: [PATCH 05/22] Paramedic Alt Title --- code/modules/jobs/job_types/job_alt_titles.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/jobs/job_types/job_alt_titles.dm b/code/modules/jobs/job_types/job_alt_titles.dm index fd080223..68e79dd5 100644 --- a/code/modules/jobs/job_types/job_alt_titles.dm +++ b/code/modules/jobs/job_types/job_alt_titles.dm @@ -54,7 +54,7 @@ alt_titles = list("Medical Director") /datum/job/doctor - alt_titles = list("Nurse", "Surgeon", "Physician") + alt_titles = list("Nurse", "Surgeon", "Physician", "Paramedic") /datum/job/chemist alt_titles = list("Pharmacist", "Pharmacologist") From 9bdbfe430f9b1c57e64a957d81d325ad4670ed79 Mon Sep 17 00:00:00 2001 From: Dip Date: Tue, 3 Nov 2020 04:55:00 -0300 Subject: [PATCH 06/22] synthblood missing recipe --- code/modules/reagents/chemistry/recipes/others.dm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index d40b1a5b..ea7f86c5 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -702,3 +702,11 @@ id = "royalbluecarpet" results = list("royalbluecarpet" = 2) required_reagents = list("carpet" = 1, "clonexadone" = 1) + +/datum/chemical_reaction/synth_blood + name = "Synthetic Blood" + id = "syntheticblood" + results = list("syntheticblood" = 3) + required_reagents = list("salglu_solution" = 1, "iron" = 1, "stable_plasma" = 1) + mix_message = "The mixture congeals and gives off a faint copper scent." + required_temp = 350 From ea5b9ca4ef91190746acc60a92be986a5bf72a06 Mon Sep 17 00:00:00 2001 From: JaySparrow Date: Wed, 4 Nov 2020 00:37:23 -0600 Subject: [PATCH 07/22] Junior roles And more! Oof ouch my soul. --- code/__DEFINES/jobs.dm | 4 + code/modules/client/preferences.dm | 2 +- code/modules/jobs/job_types/captain.dm | 6 +- code/modules/jobs/job_types/cargo_service.dm | 14 +- code/modules/jobs/job_types/engineering.dm | 81 ++++++++- code/modules/jobs/job_types/job.dm | 1 + code/modules/jobs/job_types/job_alt_titles.dm | 10 ++ code/modules/jobs/job_types/medical.dm | 71 +++++++- code/modules/jobs/job_types/science.dm | 62 ++++++- code/modules/jobs/job_types/security.dm | 163 ++++++++++++++++-- code/modules/jobs/job_types/silicon.dm | 14 +- code/modules/jobs/jobs.dm | 12 +- tgstation.dme | 6 - 13 files changed, 386 insertions(+), 60 deletions(-) diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index c90d809f..c2c160b0 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -12,6 +12,8 @@ #define ROBOTICIST (1<<8) #define AI_JF (1<<9) #define CYBORG (1<<10) +#define JR_OFFICER (1<<11) +#define JR_ENGINEER (1<<12) #define MEDSCI (1<<1) @@ -23,6 +25,8 @@ #define DOCTOR (1<<4) #define GENETICIST (1<<5) #define VIROLOGIST (1<<6) +#define JR_DOCTOR (1<<7) +#define JR_SCIENTIST (1<<9) #define CIVILIAN (1<<2) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 84f89b00..1a3e4e0b 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1103,7 +1103,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) #undef APPEARANCE_CATEGORY_COLUMN #undef MAX_MUTANT_ROWS -/datum/preferences/proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), widthPerColumn = 295, height = 620) +/datum/preferences/proc/SetChoices(mob/user, limit = 22, list/splitJobs = list("Chief Engineer"), widthPerColumn = 295, height = 620) if(!SSjob) return diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index 366d8fd2..61e3b409 100644 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -12,8 +12,8 @@ Captain supervisors = "Kinaris officials and Space law" selection_color = "#ccccff" req_admin_notify = 1 - minimal_player_age = 20 - exp_requirements = 480 + minimal_player_age = 30 + exp_requirements = 3000 exp_type = EXP_TYPE_COMMAND exp_type_department = EXP_TYPE_COMMAND @@ -84,7 +84,7 @@ Head of Personnel selection_color = "#ddddff" req_admin_notify = 1 minimal_player_age = 20 - exp_requirements = 180 + exp_requirements = 1500 exp_type = EXP_TYPE_SERVICE exp_type_department = EXP_TYPE_SERVICE diff --git a/code/modules/jobs/job_types/cargo_service.dm b/code/modules/jobs/job_types/cargo_service.dm index 445df6ce..f9655ce9 100644 --- a/code/modules/jobs/job_types/cargo_service.dm +++ b/code/modules/jobs/job_types/cargo_service.dm @@ -12,15 +12,15 @@ Quartermaster is a real head fuck you spawn_positions = 1 supervisors = "the captain" selection_color = "#d7b088" - minimal_player_age = 10 + minimal_player_age = 7 exp_type = EXP_TYPE_SUPPLY exp_type_department = EXP_TYPE_SUPPLY - exp_requirements = 300 + exp_requirements = 1200 outfit = /datum/outfit/job/quartermaster - access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_VAULT) - minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_VAULT) + access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_KEYCARD_AUTH, ACCESS_RC_ANNOUNCE, ACCESS_SEC_DOORS, ACCESS_HEADS, ACCESS_VAULT) + minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_KEYCARD_AUTH, ACCESS_RC_ANNOUNCE, ACCESS_SEC_DOORS, ACCESS_HEADS, ACCESS_VAULT) blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity) @@ -35,6 +35,10 @@ Quartermaster is a real head fuck you glasses = /obj/item/clothing/glasses/sunglasses l_hand = /obj/item/clipboard + id = /obj/item/card/id/silver + ears = /obj/item/radio/headset/heads/qm + backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1, /obj/item/modular_computer/tablet/preset/advanced = 1) + chameleon_extras = /obj/item/stamp/qm /* @@ -81,7 +85,7 @@ Shaft Miner selection_color = "#dcba97" custom_spawn_text = "Remember, you are a miner, not a hunter. Hunting monsters is not a requirement of your job, the only requirement of your job is to provide materials for the station. Don't be afraid to run away if you're inexperienced with fighting the mining area's locals." minimal_player_age = 1 - exp_requirements = 120 + exp_requirements = 600 exp_type = EXP_TYPE_CREW exp_type_department = EXP_TYPE_SUPPLY diff --git a/code/modules/jobs/job_types/engineering.dm b/code/modules/jobs/job_types/engineering.dm index b14d14cb..3514e7c8 100644 --- a/code/modules/jobs/job_types/engineering.dm +++ b/code/modules/jobs/job_types/engineering.dm @@ -13,8 +13,8 @@ Chief Engineer supervisors = "the captain" selection_color = "#ffeeaa" req_admin_notify = 1 - minimal_player_age = 20 - exp_requirements = 300 + minimal_player_age = 14 + exp_requirements = 1500 exp_type = EXP_TYPE_ENGINEERING exp_type_department = EXP_TYPE_ENGINEERING @@ -79,8 +79,9 @@ Station Engineer minimal_player_age = 1 supervisors = "the chief engineer" selection_color = "#fff5cc" - exp_requirements = 120 - exp_type = EXP_TYPE_CREW + exp_requirements = 300 + exp_type = EXP_TYPE_ENGINEERING + exp_type_department = EXP_TYPE_ENGINEERING outfit = /datum/outfit/job/engineer @@ -136,14 +137,16 @@ Atmospheric Technician minimal_player_age = 2 supervisors = "the chief engineer" selection_color = "#fff5cc" - exp_requirements = 180 - exp_type = EXP_TYPE_CREW + exp_requirements = 600 + exp_type = EXP_TYPE_ENGINEERING + exp_type_department = EXP_TYPE_ENGINEERING outfit = /datum/outfit/job/atmos access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS, - ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_MINERAL_STOREROOM) - minimal_access = list(ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS, ACCESS_EMERGENCY_STORAGE, ACCESS_CONSTRUCTION, ACCESS_MINERAL_STOREROOM) + ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM) + minimal_access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS, + ACCESS_EMERGENCY_STORAGE, ACCESS_CONSTRUCTION, ACCESS_MINERAL_STOREROOM) /datum/outfit/job/atmos name = "Atmospheric Technician" @@ -169,3 +172,65 @@ Atmospheric Technician suit = /obj/item/clothing/suit/space/hardsuit/engine/atmos suit_store = /obj/item/tank/internals/oxygen internals_slot = SLOT_S_STORE + +/* +Junior Engineer +*/ +/datum/job/junior_engineer + title = "Engineering Intern" + flag = JR_ENGINEER + department_head = list("Chief Engineer") + department_flag = ENGSEC + faction = "Station" + total_positions = 2 + spawn_positions = 2 + minimal_player_age = 0 + supervisors = "the chief engineer, and any other more experienced engineers" + selection_color = "#fff5cc" + exp_requirements = 120 + exp_type = EXP_TYPE_CREW + + outfit = /datum/outfit/job/engineer/junior + + access = list(ACCESS_TECH_STORAGE, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_MAINT_TUNNELS, + ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM) + minimal_access = list(ACCESS_TECH_STORAGE, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_MAINT_TUNNELS, + ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM) + +/datum/outfit/job/engineer/junior + name = "Engineering Intern" + jobtype = /datum/job/junior_engineer + + belt = /obj/item/storage/belt/utility/full/engi + l_pocket = /obj/item/pda/engineering + ears = /obj/item/radio/headset/headset_eng + uniform = /obj/item/clothing/under/rank/engineer + shoes = /obj/item/clothing/shoes/workboots + head = /obj/item/clothing/head/hardhat + r_pocket = /obj/item/t_scanner + + backpack = /obj/item/storage/backpack/industrial + satchel = /obj/item/storage/backpack/satchel/eng + duffelbag = /obj/item/storage/backpack/duffelbag/engineering + box = /obj/item/storage/box/engineer + pda_slot = SLOT_L_STORE + backpack_contents = list(/obj/item/modular_computer/tablet/preset/advanced=1) + +/datum/outfit/job/engineer/junior/gloved/ + name = "Station Engineer (Gloves)" + gloves = /obj/item/clothing/gloves/color/yellow + +/datum/outfit/job/engineer/junior/gloved/rig/junior + name = "Station Engineer (Hardsuit)" + + mask = /obj/item/clothing/mask/breath + suit = /obj/item/clothing/suit/space/hardsuit/engine + suit_store = /obj/item/tank/internals/oxygen + head = null + internals_slot = SLOT_S_STORE + +/datum/job/junior_engineer/after_spawn(mob/living/carbon/human/H, mob/M) //Instead of going through the process of adding spawnpoints + var/turf/T + var/spawn_point = locate(/obj/effect/landmark/start/station_engineer) in GLOB.start_landmarks_list + T = get_turf(spawn_point) + H.Move(T) \ No newline at end of file diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index ea3b1fcf..2f56fe25 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -45,6 +45,7 @@ var/outfit = null + //Minutes required in specified job or department type. var/exp_requirements = 0 var/exp_type = "" diff --git a/code/modules/jobs/job_types/job_alt_titles.dm b/code/modules/jobs/job_types/job_alt_titles.dm index fd080223..3d1bd179 100644 --- a/code/modules/jobs/job_types/job_alt_titles.dm +++ b/code/modules/jobs/job_types/job_alt_titles.dm @@ -1,3 +1,5 @@ +//This file also determines the order for the choose your occupation chances screen. + //Engineering /datum/job/chief_engineer alt_titles = list("Head Engineer", "Construction Coordinator", "Project Manager") @@ -8,6 +10,8 @@ /datum/job/atmos alt_titles = list("Firefighter", "Life Support Specialist") +/datum/job/junior_engineer + //Service /datum/job/assistant alt_titles = list("Civilian", "Visitor", "Businessman", "Trader", "Entertainer", "Tourist") @@ -49,6 +53,8 @@ /datum/job/roboticist alt_titles = list("Biomechanical Engineer", "Mechatronic Engineer", "Mechanic") +/datum/job/junior_scientist + //Medical /datum/job/cmo alt_titles = list("Medical Director") @@ -65,6 +71,8 @@ /datum/job/geneticist alt_titles = list("Gene Therapist") +/datum/job/junior_doctor + //Security /datum/job/hos alt_titles = list("Chief of Security", "Security Commander") @@ -78,6 +86,8 @@ /datum/job/detective alt_titles = list("Forensics Technician", "Private Investigator", "Gumshoe") +/datum/job/junior_officer + //Supply /datum/job/qm alt_titles = list("Supply Chief") diff --git a/code/modules/jobs/job_types/medical.dm b/code/modules/jobs/job_types/medical.dm index 2dc36c01..a6d6645b 100644 --- a/code/modules/jobs/job_types/medical.dm +++ b/code/modules/jobs/job_types/medical.dm @@ -13,8 +13,8 @@ Chief Medical Officer supervisors = "the captain" selection_color = "#ffddf0" req_admin_notify = 1 - minimal_player_age = 10 - exp_requirements = 300 + minimal_player_age = 14 + exp_requirements = 1500 exp_type = EXP_TYPE_MEDICAL exp_type_department = EXP_TYPE_MEDICAL @@ -94,6 +94,8 @@ Medical Doctor satchel = /obj/item/storage/backpack/satchel/med duffelbag = /obj/item/storage/backpack/duffelbag/med + backpack_contents = list(/obj/item/storage/hypospraykit/regular) + chameleon_extras = /obj/item/gun/syringe /* @@ -110,8 +112,10 @@ Chemist minimal_player_age = 1 supervisors = "the chief medical officer" selection_color = "#ffeef0" - exp_type = EXP_TYPE_CREW - exp_requirements = 60 + exp_requirements = 480 + exp_type = EXP_TYPE_MEDICAL + exp_type_department = EXP_TYPE_MEDICAL + outfit = /datum/outfit/job/chemist @@ -133,6 +137,8 @@ Chemist duffelbag = /obj/item/storage/backpack/duffelbag/med l_hand = /obj/item/fermichem/pHbooklet + backpack_contents = list(/obj/item/storage/hypospraykit/regular) + chameleon_extras = /obj/item/gun/syringe /* @@ -148,8 +154,9 @@ Geneticist spawn_positions = 2 supervisors = "the chief medical officer and research director" selection_color = "#ffeef0" - exp_type = EXP_TYPE_CREW - exp_requirements = 30 + exp_requirements = 480 + exp_type = EXP_TYPE_MEDICAL + exp_type_department = EXP_TYPE_MEDICAL outfit = /datum/outfit/job/geneticist @@ -186,8 +193,9 @@ Virologist minimal_player_age = 2 supervisors = "the chief medical officer" selection_color = "#ffeef0" - exp_type = EXP_TYPE_CREW - exp_requirements = 120 + exp_requirements = 600 + exp_type = EXP_TYPE_MEDICAL + exp_type_department = EXP_TYPE_MEDICAL outfit = /datum/outfit/job/virologist @@ -209,3 +217,50 @@ Virologist backpack = /obj/item/storage/backpack/virology satchel = /obj/item/storage/backpack/satchel/vir duffelbag = /obj/item/storage/backpack/duffelbag/med + + +/* +Junior Doctor +*/ +/datum/job/junior_doctor + title = "Medical Resident" + flag = JR_DOCTOR + department_head = list("Chief Medical Officer") + department_flag = MEDSCI + faction = "Station" + total_positions = 2 + spawn_positions = 2 + minimal_player_age = 0 + supervisors = "the chief medical officer, and any other senior medical staff" + selection_color = "#ffeef0" + exp_requirements = 120 + exp_type = EXP_TYPE_CREW + + outfit = /datum/outfit/job/doctor/junior + + access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM) + minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM) + +/datum/outfit/job/doctor/junior + name = "Medical Resident" + jobtype = /datum/job/junior_doctor + + belt = /obj/item/pda/medical + ears = /obj/item/radio/headset/headset_med + uniform = /obj/item/clothing/under/rank/medical + shoes = /obj/item/clothing/shoes/sneakers/white + suit = /obj/item/clothing/suit/toggle/labcoat + l_hand = /obj/item/storage/firstaid/regular + suit_store = /obj/item/flashlight/pen + + backpack = /obj/item/storage/backpack/medic + satchel = /obj/item/storage/backpack/satchel/med + duffelbag = /obj/item/storage/backpack/duffelbag/med + + chameleon_extras = /obj/item/gun/syringe + +/datum/job/junior_doctor/after_spawn(mob/living/carbon/human/H, mob/M) //Instead of going through the process of adding spawnpoints + var/turf/T + var/spawn_point = locate(/obj/effect/landmark/start/medical_doctor) in GLOB.start_landmarks_list + T = get_turf(spawn_point) + H.Move(T) \ No newline at end of file diff --git a/code/modules/jobs/job_types/science.dm b/code/modules/jobs/job_types/science.dm index 139ff568..1cd36504 100644 --- a/code/modules/jobs/job_types/science.dm +++ b/code/modules/jobs/job_types/science.dm @@ -13,10 +13,10 @@ Research Director supervisors = "the captain" selection_color = "#ffddff" req_admin_notify = 1 - minimal_player_age = 10 - exp_type_department = EXP_TYPE_SCIENCE - exp_requirements = 300 + minimal_player_age = 14 + exp_requirements = 1500 exp_type = EXP_TYPE_SCIENCE + exp_type_department = EXP_TYPE_SCIENCE outfit = /datum/outfit/job/rd @@ -71,12 +71,13 @@ Scientist department_flag = MEDSCI faction = "Station" total_positions = 5 - spawn_positions = 3 + spawn_positions = 2 minimal_player_age = 1 supervisors = "the research director" selection_color = "#ffeeff" - exp_requirements = 120 - exp_type = EXP_TYPE_CREW + exp_requirements = 480 + exp_type = EXP_TYPE_SCIENCE + exp_type_department = EXP_TYPE_SCIENCE outfit = /datum/outfit/job/scientist @@ -111,8 +112,10 @@ Roboticist minimal_player_age = 2 supervisors = "the research director" selection_color = "#ffeeff" - exp_requirements = 120 - exp_type = EXP_TYPE_CREW + exp_requirements = 300 + exp_type = EXP_TYPE_SCIENCE + exp_type_department = EXP_TYPE_SCIENCE + outfit = /datum/outfit/job/roboticist @@ -133,3 +136,46 @@ Roboticist satchel = /obj/item/storage/backpack/satchel/tox pda_slot = SLOT_L_STORE + + +/* +Junior Scientist +*/ +/datum/job/junior_scientist + title = "Research Student" + flag = JR_SCIENTIST + department_head = list("Research Director") + department_flag = MEDSCI + faction = "Station" + total_positions = 2 + spawn_positions = 1 + minimal_player_age = 0 + supervisors = "the research director, and any other senior science staff" + selection_color = "#ffeeff" + exp_requirements = 120 + exp_type = EXP_TYPE_CREW + + + outfit = /datum/outfit/job/scientist/junior + + access = list(ACCESS_ROBOTICS, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM, ACCESS_TECH_STORAGE, ACCESS_GENETICS) + minimal_access = list(ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM) + +/datum/outfit/job/scientist/junior + name = "Scientist" + jobtype = /datum/job/scientist + + belt = /obj/item/pda/toxins + ears = /obj/item/radio/headset/headset_sci + uniform = /obj/item/clothing/under/rank/scientist + shoes = /obj/item/clothing/shoes/sneakers/white + suit = /obj/item/clothing/suit/toggle/labcoat/science + + backpack = /obj/item/storage/backpack/science + satchel = /obj/item/storage/backpack/satchel/tox + +/datum/job/junior_scientist/after_spawn(mob/living/carbon/human/H, mob/M) //Instead of going through the process of adding spawnpoints + var/turf/T + var/spawn_point = locate(/obj/effect/landmark/start/scientist) in GLOB.start_landmarks_list + T = get_turf(spawn_point) + H.Move(T) \ No newline at end of file diff --git a/code/modules/jobs/job_types/security.dm b/code/modules/jobs/job_types/security.dm index 927461bd..b2b0271f 100644 --- a/code/modules/jobs/job_types/security.dm +++ b/code/modules/jobs/job_types/security.dm @@ -20,7 +20,7 @@ Head of Security selection_color = "#ffdddd" req_admin_notify = 1 minimal_player_age = 20 - exp_requirements = 420 + exp_requirements = 2000 exp_type = EXP_TYPE_SECURITY exp_type_department = EXP_TYPE_SECURITY @@ -87,9 +87,10 @@ Warden spawn_positions = 1 supervisors = "the head of security" selection_color = "#ffeeee" - minimal_player_age = 3 - exp_requirements = 360 - exp_type = EXP_TYPE_CREW + minimal_player_age = 9 + exp_requirements = 720 + exp_type = EXP_TYPE_SECURITY + exp_type_department = EXP_TYPE_SECURITY outfit = /datum/outfit/job/warden @@ -118,7 +119,9 @@ Warden glasses = /obj/item/clothing/glasses/hud/security/sunglasses r_pocket = /obj/item/assembly/flash/handheld l_pocket = /obj/item/restraints/handcuffs - suit_store = /obj/item/gun/energy/e_gun/advtaser + //suit_store = /obj/item/gun/energy/e_gun/advtaser + suit_store = /obj/item/gun/energy/pumpaction/defender + backpack_contents = list(/obj/item/melee/baton/loaded=1) backpack = /obj/item/storage/backpack/security @@ -143,9 +146,10 @@ Detective spawn_positions = 1 supervisors = "the head of security" selection_color = "#ffeeee" - minimal_player_age = 2 + minimal_player_age = 5 exp_requirements = 300 - exp_type = EXP_TYPE_CREW + exp_type = EXP_TYPE_SECURITY + exp_type_department = EXP_TYPE_SECURITY outfit = /datum/outfit/job/detective @@ -199,9 +203,10 @@ Security Officer spawn_positions = 5 //Handled in /datum/controller/occupations/proc/setup_officer_positions() supervisors = "the head of security, and the head of your assigned department (if applicable)" selection_color = "#ffeeee" - minimal_player_age = 1 - exp_requirements = 300 - exp_type = EXP_TYPE_CREW + minimal_player_age = 5 + exp_requirements = 420 + exp_type = EXP_TYPE_SECURITY + exp_type_department = EXP_TYPE_SECURITY outfit = /datum/outfit/job/security @@ -344,3 +349,141 @@ GLOBAL_LIST_INIT(available_depts, list(SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, S /obj/item/radio/headset/headset_sec/alt/department/sci keyslot = new /obj/item/encryptionkey/headset_sec keyslot2 = new /obj/item/encryptionkey/headset_sci + + +/* +Junior Security Officer +*/ +/datum/job/junior_officer + title = "Rookie" + flag = JR_OFFICER + department_head = list("Head of Security") + department_flag = ENGSEC + faction = "Station" + total_positions = 5 //Handled in /datum/controller/occupations/proc/setup_officer_positions() + spawn_positions = 5 //Handled in /datum/controller/occupations/proc/setup_officer_positions() + supervisors = "the head of security, and the head of your assigned department (if applicable), and any other senior officer" + selection_color = "#ffeeee" + minimal_player_age = 3 + exp_requirements = 300 + exp_type = EXP_TYPE_CREW + + outfit = /datum/outfit/job/security/junior + + access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM) + minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MINERAL_STOREROOM) //BUT SEE /DATUM/JOB/WARDEN/GET_ACCESS() + + mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM) + blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/nonviolent, /datum/quirk/paraplegic) + + +/datum/job/junior_officer/get_access() + var/list/L = list() + L |= ..() | check_config_for_sec_maint() + return L + +/datum/job/junior_officer/after_spawn(mob/living/carbon/human/H, mob/M) + // Assign department security + var/department + if(M && M.client && M.client.prefs) + department = M.client.prefs.prefered_security_department + if(!LAZYLEN(GLOB.available_depts) || department == "None") + return + else if(department in GLOB.available_depts) + LAZYREMOVE(GLOB.available_depts, department) + else + department = pick_n_take(GLOB.available_depts) + var/ears = null + var/accessory = null + var/list/dep_access = null + var/destination = null + var/spawn_point = locate(/obj/effect/landmark/start/security_officer) in GLOB.start_landmarks_list + switch(department) + if(SEC_DEPT_SUPPLY) + ears = /obj/item/radio/headset/headset_sec/alt/department/supply + dep_access = list(ACCESS_MAILSORTING, ACCESS_MINING, ACCESS_MINING_STATION) + destination = /area/security/checkpoint/supply + spawn_point = locate(/obj/effect/landmark/start/depsec/supply) in GLOB.department_security_spawns + accessory = /obj/item/clothing/accessory/armband/cargo + if(SEC_DEPT_ENGINEERING) + ears = /obj/item/radio/headset/headset_sec/alt/department/engi + dep_access = list(ACCESS_CONSTRUCTION, ACCESS_ENGINE) + destination = /area/security/checkpoint/engineering + spawn_point = locate(/obj/effect/landmark/start/depsec/engineering) in GLOB.department_security_spawns + accessory = /obj/item/clothing/accessory/armband/engine + if(SEC_DEPT_MEDICAL) + ears = /obj/item/radio/headset/headset_sec/alt/department/med + dep_access = list(ACCESS_MEDICAL) + destination = /area/security/checkpoint/medical + spawn_point = locate(/obj/effect/landmark/start/depsec/medical) in GLOB.department_security_spawns + accessory = /obj/item/clothing/accessory/armband/medblue + if(SEC_DEPT_SCIENCE) + ears = /obj/item/radio/headset/headset_sec/alt/department/sci + dep_access = list(ACCESS_RESEARCH) + destination = /area/security/checkpoint/science + spawn_point = locate(/obj/effect/landmark/start/depsec/science) in GLOB.department_security_spawns + accessory = /obj/item/clothing/accessory/armband/science + + if(accessory) + var/obj/item/clothing/under/U = H.w_uniform + U.attach_accessory(new accessory) + if(ears) + if(H.ears) + qdel(H.ears) + H.equip_to_slot_or_del(new ears(H),SLOT_EARS) + + var/obj/item/card/id/W = H.wear_id + W.access |= dep_access + + var/teleport = 0 + if(!CONFIG_GET(flag/sec_start_brig)) + if(destination || spawn_point) + teleport = 1 + if(teleport) + var/turf/T + if(spawn_point) + T = get_turf(spawn_point) + H.Move(T) + else + var/safety = 0 + while(safety < 25) + T = safepick(get_area_turfs(destination)) + if(T && !H.Move(T)) + safety += 1 + continue + else + break + if(department) + to_chat(M, "You have been assigned to [department]!") + else + to_chat(M, "You have not been assigned to any department. Patrol the halls and help where needed.") + + + +/datum/outfit/job/security/junior + name = "Security Officer" + jobtype = /datum/job/officer + + belt = /obj/item/pda/security + ears = /obj/item/radio/headset/headset_sec/alt + uniform = /obj/item/clothing/under/rank/security + gloves = /obj/item/clothing/gloves/color/black + head = /obj/item/clothing/head/helmet/sec + suit = /obj/item/clothing/suit/armor/vest/alt + shoes = /obj/item/clothing/shoes/jackboots + l_pocket = /obj/item/restraints/handcuffs + r_pocket = /obj/item/assembly/flash/handheld + suit_store = /obj/item/gun/energy/e_gun/advtaser + backpack_contents = list(/obj/item/melee/baton/loaded=1) + + backpack = /obj/item/storage/backpack/security + satchel = /obj/item/storage/backpack/satchel/sec + duffelbag = /obj/item/storage/backpack/duffelbag/sec + box = /obj/item/storage/box/security + + implants = list(/obj/item/implant/mindshield) + + chameleon_extras = list(/obj/item/gun/energy/e_gun/advtaser, /obj/item/clothing/glasses/hud/security/sunglasses, /obj/item/clothing/head/helmet) + //The helmet is necessary because /obj/item/clothing/head/helmet/sec is overwritten in the chameleon list by the standard helmet, which has the same name and icon state + + diff --git a/code/modules/jobs/job_types/silicon.dm b/code/modules/jobs/job_types/silicon.dm index 74746404..8fb5b029 100644 --- a/code/modules/jobs/job_types/silicon.dm +++ b/code/modules/jobs/job_types/silicon.dm @@ -11,10 +11,10 @@ AI selection_color = "#ccffcc" supervisors = "your laws" req_admin_notify = TRUE - minimal_player_age = 5 - exp_requirements = 1200 - exp_type = EXP_TYPE_CREW -// exp_type_department = EXP_TYPE_SILICON + minimal_player_age = 14 + exp_requirements = 1800 + //exp_type = EXP_TYPE_CREW + exp_type_department = EXP_TYPE_SILICON var/do_special_check = TRUE /datum/job/ai/equip(mob/living/carbon/human/H, visualsOnly, announce, latejoin, outfit_override) @@ -78,9 +78,9 @@ Cyborg spawn_positions = 1 supervisors = "your laws and the AI" //Nodrak selection_color = "#ddffdd" -// minimal_player_age = 0 -// exp_requirements = 120 -// exp_type = EXP_TYPE_CREW + minimal_player_age = 0 + exp_requirements = 300 + exp_type = EXP_TYPE_CREW /datum/job/cyborg/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE, latejoin = FALSE, outfit_override = null) return H.Robotize(FALSE, latejoin) diff --git a/code/modules/jobs/jobs.dm b/code/modules/jobs/jobs.dm index d4c9ac2b..1121b399 100644 --- a/code/modules/jobs/jobs.dm +++ b/code/modules/jobs/jobs.dm @@ -10,7 +10,8 @@ GLOBAL_LIST_INIT(command_positions, list( GLOBAL_LIST_INIT(engineering_positions, list( "Chief Engineer", "Station Engineer", - "Atmospheric Technician")) + "Atmospheric Technician", + "Engineering Intern")) GLOBAL_LIST_INIT(medical_positions, list( @@ -18,13 +19,15 @@ GLOBAL_LIST_INIT(medical_positions, list( "Medical Doctor", "Geneticist", "Virologist", - "Chemist")) + "Chemist", + "Medical Resident")) GLOBAL_LIST_INIT(science_positions, list( "Research Director", "Scientist", - "Roboticist")) + "Roboticist", + "Research Student")) GLOBAL_LIST_INIT(supply_positions, list( "Quartermaster", @@ -48,7 +51,8 @@ GLOBAL_LIST_INIT(security_positions, list( "Head of Security", "Warden", "Detective", - "Security Officer")) + "Security Officer", + "Rookie")) GLOBAL_LIST_INIT(nonhuman_positions, list( diff --git a/tgstation.dme b/tgstation.dme index e25da626..4e7771a5 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3146,12 +3146,6 @@ #include "modular_citadel\code\modules\food_and_drinks\snacks\meat.dm" #include "modular_citadel\code\modules\integrated_electronics\subtypes\manipulation.dm" #include "modular_citadel\code\modules\jobs\dresscode_values.dm" -#include "modular_citadel\code\modules\jobs\job_types\captain.dm" -#include "modular_citadel\code\modules\jobs\job_types\cargo_service.dm" -#include "modular_citadel\code\modules\jobs\job_types\engineering.dm" -#include "modular_citadel\code\modules\jobs\job_types\medical.dm" -#include "modular_citadel\code\modules\jobs\job_types\science.dm" -#include "modular_citadel\code\modules\jobs\job_types\security.dm" #include "modular_citadel\code\modules\keybindings\bindings_carbon.dm" #include "modular_citadel\code\modules\keybindings\bindings_human.dm" #include "modular_citadel\code\modules\keybindings\bindings_robot.dm" From dbc0d7c1a0e18d4d2357f95fe2bd8ec9562aeda6 Mon Sep 17 00:00:00 2001 From: Dip Date: Thu, 5 Nov 2020 16:09:38 -0300 Subject: [PATCH 08/22] Large beakers to department lathes, large hypovial research --- .../autolathe_designs_medical_and_dinnerware.dm | 6 ++++-- code/modules/research/techweb/all_nodes.dm | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm index 6f6fb0c8..be55ed17 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm @@ -159,10 +159,11 @@ /datum/design/large_beaker name = "Large Beaker" id = "large_beaker" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_GLASS = 2500) build_path = /obj/item/reagent_containers/glass/beaker/large category = list("initial", "Medical") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/healthanalyzer name = "Health Analyzer" @@ -208,7 +209,8 @@ /datum/design/hypoviallarge name = "Large Hypovial" id = "large_hypovial" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 2500) build_path = /obj/item/reagent_containers/glass/bottle/vial/large category = list("initial","Medical") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 5dee32a5..4701bf2b 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -12,7 +12,7 @@ "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "space_heater", "xlarge_beaker", "sec_rshot", "sec_bshot", "sec_slug", "sec_Islug", "sec_dart", "sec_38", "sec_38lethal", "rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass","chem_pack","medkit_cabinet", - "disposable_hypospray","plastic_knife","plastic_fork","plastic_spoon") + "disposable_hypospray","plastic_knife","plastic_fork","plastic_spoon","large_beaker") /datum/techweb_node/mmi id = "mmi" @@ -81,7 +81,7 @@ display_name = "Advanced Biotechnology" description = "Advanced Biotechnology" prereq_ids = list("biotech") - design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med","smartdartgun","medicinalsmartdart", "pHmeter") + design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med","smartdartgun","medicinalsmartdart", "pHmeter", "large_hypovial") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 From 124a266e9a0fa1f3c85e493158446a522f366ae4 Mon Sep 17 00:00:00 2001 From: Dip Date: Thu, 5 Nov 2020 23:57:54 -0300 Subject: [PATCH 09/22] stack size --- code/game/objects/items/storage/firstaid.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm index dc048e3e..5321b5ef 100644 --- a/code/game/objects/items/storage/firstaid.dm +++ b/code/game/objects/items/storage/firstaid.dm @@ -30,7 +30,6 @@ /obj/item/storage/firstaid/regular/PopulateContents() if(empty) return - new /obj/item/stack/medical/plaster_gauze(src) new /obj/item/stack/medical/gauze(src) new /obj/item/stack/medical/bruise_pack(src) new /obj/item/stack/medical/bruise_pack(src) From 0eb87e48461a94c7b22fe8df80729144992bb84c Mon Sep 17 00:00:00 2001 From: Dip Date: Sat, 7 Nov 2020 11:09:49 -0300 Subject: [PATCH 10/22] NT to Kinaris text changes --- .../modules/reagents/reagent_containers/pill.dm | 2 +- strings/redpill.json | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 38880f66..c40df151 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -47,7 +47,7 @@ "[user] forces [M] to [apply_method] [src].") var/makes_me_think = pick(strings("redpill.json", "redpill_questions")) - if(icon_state == "pill4" && prob(5)) //you take the red pill - you stay in Wonderland, and I show you how deep the rabbit hole goes + if(icon_state == "pill4" && prob(10)) //you take the red pill - you stay in Wonderland, and I show you how deep the rabbit hole goes addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, M, "[makes_me_think]"), 50) log_combat(user, M, "fed", reagents.log_list()) diff --git a/strings/redpill.json b/strings/redpill.json index 3f65db73..d12adc76 100644 --- a/strings/redpill.json +++ b/strings/redpill.json @@ -4,7 +4,7 @@ "Why is it called the emergency shuttle if it arrives every single shift?", "Where does the Cook get all this meat from?", "Space wind? How does that even make sense?", - "Why does Nanotrasen hire Clowns and Mimes for every single station?", + "Why does Kinaris hire Clowns and Mimes for every single station?", "Why is the station's air supply connected to the plasma tank?", "Why are there fire alarms everywhere but no sprinklers?", "Why is this a plasma research station if we know everything about plasma already?", @@ -16,16 +16,16 @@ "How come a hole in the floor doesn't suck you out into space?", "Why is space cold?", "Why does space circle around on itself?", - "Nanotrasen just clones us every shift.", + "Kinaris just clones us every shift.", "There's no biological difference between lizards and humans.", "Why is there a floor, but no roof?", - "The universe always ends after we reach Centcomm.", + "The universe always ends after we reach CentCom.", "Everyone is controlled by strings behind a glowing screen", "Seperation is absolute.", "It doesn't take much for people to murder their friends.", "All the crew are just greytiders with different paint.", - "What the fuck is CO2?", - "2008 was 550 years ago.", + "What the fuck is carbon dioxide?", + "2010 was 550 years ago.", "This is all an endless looping nightmare of misery.", "The ultimate god is really really stoned.", "Space stations are no substitute for healthy social interaction.", @@ -33,11 +33,14 @@ "How do mirrors give people haircuts?", "Why is this station so poorly designed?", "How can an escape pod only take two people normally, but an infinite number of people if they're lying down?", - "Why do only lizards get their own native language?", "Why do people just randomly murder all their friends some shifts?", "If magic is real, why aren't we researching that?", "How is everyone a complete expert in every threat in the universe?", "If suit sensors are so important, why don't they always start maximized?", - "If we can wash clothes in a sink, why do we need washing machines?" + "If we can wash clothes in a sink, why do we need washing machines?", + "Why are the dormitories protected from radiation storms but the rest of the station isn't?", + "If people can have a dick that's twice their size, how come they don't die of bloodloss when they get hard?", + "Why do rods not get vaporized by the supermatter?", + "Why do I never have to use the bathroom?" ] } From b7f296aaa3ecdac651f17affb7c892352eb61ed1 Mon Sep 17 00:00:00 2001 From: Dip Date: Sat, 7 Nov 2020 11:11:03 -0300 Subject: [PATCH 11/22] Typo --- strings/redpill.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/redpill.json b/strings/redpill.json index d12adc76..2526d254 100644 --- a/strings/redpill.json +++ b/strings/redpill.json @@ -40,7 +40,7 @@ "If we can wash clothes in a sink, why do we need washing machines?", "Why are the dormitories protected from radiation storms but the rest of the station isn't?", "If people can have a dick that's twice their size, how come they don't die of bloodloss when they get hard?", - "Why do rods not get vaporized by the supermatter?", + "How come immovable rods never get vaporized by the supermatter, but everything else does?", "Why do I never have to use the bathroom?" ] } From 41f9ebc80a76db6d1733dd651cca785c3c4e5d2a Mon Sep 17 00:00:00 2001 From: JaySparrow Date: Sun, 8 Nov 2020 13:56:58 -0600 Subject: [PATCH 12/22] Dynamic tweaks And a couple bugfixes. Heart attacks only target the station z level. Diseases now only spawn once. --- .../gamemodes/dynamic/dynamic_rulesets.dm | 2 +- .../dynamic/dynamic_rulesets_events.dm | 169 +++++------------- .../dynamic/dynamic_rulesets_midround.dm | 4 +- .../dynamic/dynamic_rulesets_roundstart.dm | 21 +-- code/modules/events/heart_attack.dm | 2 +- 5 files changed, 49 insertions(+), 149 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index b1e115b0..fa944b17 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -27,7 +27,7 @@ var/list/exclusive_roles = list() /// If set, there needs to be a certain amount of players doing those roles (among the players who won't be drafted) for the rule to be drafted IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS. var/list/enemy_roles = list() - /// If enemy_roles was set, this is the amount of enemy job workers needed per GLOB.dynamic_chaos_level range (0-0.5, 0.5-1.0) IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS. + /// If enemy_roles was set, this is the amount of enemy job workers needed per threat_level range (0-10,10-20,etc) IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS. var/required_enemies = list(1,1,0,0,0,0,0,0,0,0) /// The rule needs this many candidates (post-trimming) to be executed (example: Cult needs 4 players at round start) var/required_candidates = 0 diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm index c5dbea95..9b489fab 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_events.dm @@ -26,9 +26,8 @@ continue // Dead players cannot count as opponents if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles))) job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it - - var/chaos = min(max(round(GLOB.dynamic_chaos_level * 2), 0), 9) - if (job_check < required_enemies[chaos]) + var/threat = max(min(round(mode.threat_level/10),9),1) //min() to stop index errors at 100 threat //Max to stop breaking at 0 threat. + if (job_check < required_enemies[threat]) return FALSE return ..() @@ -104,7 +103,7 @@ typepath = /datum/round_event/pirates antag_flag = ROLE_TRAITOR enemy_roles = list("AI","Security Officer","Head of Security","Captain") - required_enemies = list(2,2,2,2,1,1,1,1,0,0) + required_enemies = list(3,3,2,2,2,1,1,1,1,0) weight = 3 cost = 0 earliest_start = 50 MINUTES @@ -120,82 +119,6 @@ return FALSE return ..() -/* //not currently functional -////////////////////////////////////////// -// // -// LEWD // -// // -////////////////////////////////////////// - -//Might move this to midround antags, but I don't want it messing with the weights of regular antags right now -//Only drops one horny antag at a time anyways - -/datum/dynamic_ruleset/event/lewd - name = "Horny Traitor" - //config_tag = "pirates" - //typepath = /datum/round_event/pirates - antag_flag = ROLE_LEWD_TRAITOR - antag_datum = /datum/antagonist/traitor/lewd - enemy_roles = list() - required_enemies = list(0,0,0,0,0,0,0,0,0,0) - protected_roles = list("AI","Cyborg") - restricted_roles = list("Cyborg","AI") - weight = 300 //JAY CHANGE THIS WHEN YOU ARE DONE TESTING - cost = 0 - earliest_start = 50 MINUTES - //blocking_rules = list(/datum/dynamic_ruleset/roundstart/nuclear,/datum/dynamic_ruleset/midround/from_ghosts/nuclear) - requirements = list(10,10,10,10,10,10,10,10,10,10) - high_population_requirement = 10 - occurances_max = 2 - chaos_min = 0 - chaos_max = 2.5 - minimum_required_age = 7 - admin_required = TRUE - var/list/mob/living/carbon/human/lewd_candidates = list() - var/list/mob/living/carbon/human/targets = list() - var/num_lewd_traitors = 1 //The number of lewds to drop in - var/numTraitors = 0 //Variable for later. Don't touch. - earliest_start = 0 MINUTES - - -/datum/dynamic_ruleset/event/lewd/ready(forced = FALSE) - //to_chat(GLOB.admins, "makeLewd_traitors called") - //var/datum/game_mode/traitor/lewd/temp = new - - //if(CONFIG_GET(flag/protect_roles_from_antagonist)) - //continue - - //if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - //continue - - //var/mob/living/carbon/human/T = null - - for(var/mob/living/carbon/human/target in CURRENT_LIVING_PLAYERS) - if(target.client.prefs.noncon) - if(!(target.job in restricted_roles)) - targets += target - - if(lewd_candidates.len) - numTraitors = min(candidates.len, targets.len, num_lewd_traitors) - if(numTraitors == 0) - to_chat(GLOB.admins, "No lewd traitors created. Are there any valid targets?") - return 0 - return ..() - - - return 0 - - -/datum/dynamic_ruleset/event/lewd/execute(forced = FALSE) - var/mob/living/carbon/human/H = null - if(numTraitors) - for(var/i = 0, i 15 && mode.threat > 15 && prob(30)) name = "Clogged Vents: Catastrophic" cost = 15 - required_enemies = list(4,4,4,3,3,3,2,1,1,0) + required_enemies = list(4,4,4,3,3,3,2,1,1,1) typepath = /datum/round_event/vent_clog/catastrophic chaos_min = 1.8 else @@ -293,12 +216,12 @@ //config_tag = "meteor_wave" typepath = /datum/round_event/meteor_wave enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Captain","Cyborg") - required_enemies = list(2,2,2,2,2,1,1,1,0,0) + required_enemies = list(2,2,2,2,2,2,2,2,1,1) cost = 0 weight = 2 earliest_start = 45 MINUTES repeatable_weight_decrease = 2 - requirements = list(101,101,15,15,15,15,15,15,10,10) + requirements = list(101,101,25,25,20,20,15,15,10,10) high_population_requirement = 30 //property_weights = list("extended" = -2) occurances_max = 2 @@ -315,14 +238,14 @@ name = "Meteor Wave: Catastrophic" cost = 10 typepath = /datum/round_event/meteor_wave/catastrophic - required_enemies = list(3,3,3,3,3,2,2,1,1,0) + required_enemies = list(3,3,3,3,3,2,2,2,2,2) requirements = list(101,101,40,30,30,30,30,30,30,30) chaos_min = 2.0 else name = "Meteor Wave: Normal" cost = 5 typepath = /datum/round_event/meteor_wave - chaos_min = 1.2 + chaos_min = 1.5 required_enemies = list(2,2,2,2,1,1,1,1,0,0) return ..() @@ -338,11 +261,11 @@ typepath = /datum/round_event/anomaly/anomaly_bluespace enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain") required_enemies = list(2,2,2,1,1,1,1,1,1,0) - weight = 3 + weight = 2 earliest_start = 20 MINUTES repeatable_weight_decrease = 2 cost = 0 - requirements = list(101,101,5,5,5,5,5,5,5,5) + requirements = list(101,101,10,5,5,5,5,5,5,5) high_population_requirement = 5 repeatable = TRUE //property_weights = list("extended" = 1) @@ -358,8 +281,8 @@ weight = 3 earliest_start = 20 MINUTES repeatable_weight_decrease = 2 - cost = 3 - requirements = list(101,5,5,5,5,5,5,5,5,5) + cost = 2 + requirements = list(101,101,10,5,5,5,5,5,5,5) high_population_requirement = 10 repeatable = TRUE //property_weights = list("extended" = 1) @@ -370,10 +293,10 @@ name = "Anomaly: Gravitational" //config_tag = "anomaly_gravitational" typepath = /datum/round_event/anomaly/anomaly_grav - weight = 4 + weight = 3 repeatable_weight_decrease = 1 cost = 0 - requirements = list(5,4,3,2,1,0,0,0,0,0) + requirements = list(101,4,3,2,1,0,0,0,0,0) high_population_requirement = 5 repeatable = TRUE //property_weights = list("extended" = 1) @@ -407,7 +330,7 @@ cost = 0 enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") required_enemies = list(3,3,3,2,2,2,2,2,2,0) - requirements = list(101,101,10,10,10,10,10,10,10,10) + requirements = list(101,101,101,10,10,10,10,10,10,10) high_population_requirement = 10 repeatable = TRUE //property_weights = list("extended" = 1) @@ -427,7 +350,7 @@ required_enemies = list(0,0,0,0,0,0,0,0,0,0) weight = 0 //This is changed in nuclearbomb.dm occurances_max = 1 - requirements = list(10,5,0,0,0,0,0,0,0,0) //SECURE THAT DISK + requirements = list(10,10,10,10,10,10,10,10,10,10) //SECURE THAT DISK cost = 50 chaos_min = 0.5 @@ -457,7 +380,7 @@ repeatable_weight_decrease = 1 cost = 0 enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg") - required_enemies = list(2,1,1,1,1,1,0,0,0,0) + required_enemies = list(3,2,2,2,1,1,1,0,0,0) requirements = list(101,25,20,15,15,15,10,10,10,10) high_population_requirement = 10 repeatable = TRUE @@ -469,10 +392,10 @@ name = "Carp Migration" //config_tag = "carp_migration" typepath = /datum/round_event/carp_migration - weight = 5 - repeatable_weight_decrease = 3 + weight = 4 + repeatable_weight_decrease = 2 cost = 4 - requirements = list(101,5,5,1,1,1,1,1,1,1) + requirements = list(101,5,5,5,5,1,1,1,1,1) high_population_requirement = 10 earliest_start = 10 MINUTES repeatable = TRUE @@ -563,8 +486,8 @@ weight = 2 earliest_start = 30 MINUTES repeatable_weight_decrease = 1 - enemy_roles = list("Medical Doctor","Chief Medical Officer") - required_enemies = list(2,2,2,2,2,2,2,2,2,0) + enemy_roles = list("Medical Doctor","Chief Medical Officer", "Chemist") + required_enemies = list(3,3,2,2,2,2,2,2,2,1) requirements = list(101,101,101,10,5,5,5,5,5,5) high_population_requirement = 5 repeatable = TRUE @@ -579,7 +502,7 @@ weight = 2 repeatable_weight_decrease = 2 enemy_roles = list("Chemist","Chief Medical Officer","Geneticist","Medical Doctor","AI","Captain") - required_enemies = list(1,1,1,1,1,1,1,1,1,0) + required_enemies = list(2,2,2,2,1,1,1,1,1,0) requirements = list(5,5,5,5,5,5,5,5,5,5) high_population_requirement = 5 //property_weights = list("extended" = 1,"chaos" = 1) @@ -592,13 +515,13 @@ cost = 0 weight = 1 enemy_roles = list("Head of Security","Security Officer","AI","Captain","Shaft Miner") - required_enemies = list(2,2,2,2,2,2,2,2,2,0) + required_enemies = list(2,2,2,2,2,2,2,2,2,2) requirements = list(101,101,40,35,30,30,30,30,25,20) high_population_requirement = 30 earliest_start = 40 MINUTES //property_weights = list("teamwork" = 1,"chaos" = 1, "extended" = -1) occurances_max = 1 - chaos_min = 1.0 + chaos_min = 1.3 /datum/dynamic_ruleset/event/wormholes @@ -624,12 +547,12 @@ weight = 1 earliest_start = 40 MINUTES enemy_roles = list("AI","Security Officer","Head of Security","Captain","Station Engineer","Atmos Technician","Chief Engineer") - required_enemies = list(4,4,4,4,3,3,3,3,2,0) + required_enemies = list(4,4,4,4,3,3,3,3,2,2) requirements = list(101,101,50,40,40,40,40,35,30,30) high_population_requirement = 5 //property_weights = list("extended" = -2) occurances_max = 1 - chaos_min = 2.0 + chaos_min = 1.5 /datum/dynamic_ruleset/event/sentient_disease name = "Sentient Disease" @@ -640,7 +563,7 @@ required_candidates = 1 weight = 4 cost = -5 - requirements = list(101,30,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"! + requirements = list(101,101,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"! //property_weights = list("story_potential" = 1, "extended" = 1, "valid" = -2) high_population_requirement = 5 occurances_max = 1 @@ -655,7 +578,7 @@ required_candidates = 1 weight = 4 cost = 5 - requirements = list(101,30,27,24,21,18,15,15,10,10) + requirements = list(101,101,23,21,18,18,15,15,10,10) high_population_requirement = 15 //property_weights = list("story_potential" = -2, "extended" = -1) occurances_max = 1 //Skyrat change. @@ -667,7 +590,7 @@ typepath = /datum/round_event/immovable_rod enemy_roles = list("Research Director","Chief Engineer","Station Engineer","Captain","Chaplain","AI") required_enemies = list(2,2,2,2,2,2,1,1,1,0) - requirements = list(101,101,18,16,14,12,10,8,6,6) + requirements = list(101,101,20,18,16,14,12,10,8,6) high_population_requirement = 15 cost = 0 occurances_max = 2 @@ -741,29 +664,16 @@ repeatable = TRUE occurances_max = 2 -/datum/dynamic_ruleset/event/disease_outbreak/execute() //I do not know why this is necessary - var/datum/round_event_control/E = locate(/datum/round_event_control/disease_outbreak) in SSevents.control - var/datum/round_event/event = E.runEvent() //But it is. - event.announceWhen = -1 //So it isn't double announced. - return ..() - -/datum/dynamic_ruleset/event/falsealarm //I THINK IT WORKS +/datum/dynamic_ruleset/event/falsealarm name = "False Alarm" controller = /datum/round_event_control/falsealarm typepath = /datum/round_event/falsealarm - requirements = list(0,0,0,0,0,0,0,0,0,0) + requirements = list(5,5,5,5,5,5,5,5,5,5) //Tell me lieeeess high_population_requirement = 0 weight = 5 repeatable = TRUE occurances_max = 5 -///datum/dynamic_ruleset/event/falsealarm/execute() //I do not know why this is necessary - //var/datum/round_event_control/E = locate(/datum/round_event_control/falsealarm) in SSevents.control - //var/datum/round_event/event = E.runEvent() - //event.announceWhen = -1 //So it isn't double announced. - //E.runEvent() - //return ..() - /datum/dynamic_ruleset/event/grid_check name = "Grid Check" typepath = /datum/round_event/grid_check @@ -801,7 +711,7 @@ typepath = /datum/round_event/grey_tide enemy_roles = list("Chief Engineer","Station Engineer","Captain","Atmospheric Technician","AI","Cyborg") required_enemies = list(3,2,2,2,2,2,1,1,1,0) - requirements = list(101,101,5,5,5,5,5,5,5,5) + requirements = list(101,101,101,5,5,5,5,5,5,5) high_population_requirement = 0 repeatable = TRUE weight = 4 @@ -813,7 +723,8 @@ typepath = /datum/round_event/ghost_role/sentience requirements = list(101,101,0,0,0,0,0,0,0,0) high_population_requirement = 0 - weight = 1 + weight = 5 + repeatable_weight_decrease = 1 /datum/dynamic_ruleset/event/shuttle_loan name = "Shuttle Loan" @@ -844,8 +755,8 @@ /datum/dynamic_ruleset/event/spontaneous_appendicitis name = "Spontaneous Appendicitis" typepath = /datum/round_event/spontaneous_appendicitis - enemy_roles = list("Medical Doctor","Chief Medical Officer") - required_enemies = list(2,2,1,1,1,1,1,1,1,0) + enemy_roles = list("Medical Doctor","Chief Medical Officer","Roboticist") + required_enemies = list(2,2,2,2,2,2,2,1,1,1) requirements = list(5,5,5,5,5,5,5,5,0,0) high_population_requirement = 5 weight = 5 diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 8aaab0cb..65afdc7c 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -282,8 +282,8 @@ antag_flag = ROLE_LEWD_TRAITOR antag_datum = /datum/antagonist/traitor/lewd //minimum_required_age = 7 - protected_roles = list("AI","Cyborg") - restricted_roles = list("Cyborg","AI") + protected_roles = list("AI","Cyborg", "Positronic Brain") + restricted_roles = list("Cyborg","AI", "Positronic Brain") required_candidates = 1 weight = 2 cost = 0 diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index f6c90a90..5d55c210 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -16,7 +16,7 @@ required_candidates = 1 weight = 5 cost = 10 - requirements = list(101,40,30,25,20,20,15,15,15,15) + requirements = list(101,101,30,25,20,20,15,15,15,15) high_population_requirement = 10 var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) chaos_min = 2.5 @@ -31,9 +31,9 @@ //protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Cyborg") restricted_roles = list("Cyborg") //required_candidates = 1 - //weight = 5 + weight = 5 cost = 0 - requirements = list(101,25,25,20,20,15,15,10,10,5) + requirements = list(101,25,25,20,20,15,15,10,10,10) high_population_requirement = 10 //var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec) chaos_min = 2.0 @@ -76,9 +76,9 @@ protected_roles = list("AI","Cyborg") restricted_roles = list("Cyborg","AI") required_candidates = 1 - weight = 3 + weight = 2 cost = 0 - requirements = list(101,10,10,10,10,10,10,10,10,10) + requirements = list(10,10,10,10,10,10,10,10,10,10) high_population_requirement = 10 chaos_min = 0.1 chaos_max = 2.5 @@ -115,17 +115,6 @@ M.mind.restricted_roles = restricted_roles return TRUE -/* -/datum/dynamic_ruleset/roundstart/traitor/lewd/execute() - var/datum/mind/M = null - if(numTraitors) - for(var/i = 0, i Date: Mon, 9 Nov 2020 20:45:29 +0000 Subject: [PATCH 13/22] New erect penis sprites. New erect penis sprites. --- .../organs/genitals_sprite_accessories.dm | 5 +++++ .../icons/obj/genitals/breasts_onmob.dmi | Bin 12107 -> 12176 bytes .../icons/obj/genitals/penis_onmob.dmi | Bin 11470 -> 11737 bytes .../icons/obj/genitals/testicles_onmob.dmi | Bin 1137 -> 1713 bytes 4 files changed, 5 insertions(+) diff --git a/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm b/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm index 58bf4fb2..d6f6dbe7 100644 --- a/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm +++ b/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm @@ -90,6 +90,11 @@ name = "Single" alt_aroused = TRUE +/datum/sprite_accessory/testicles/sheath + icon_state = "sheath" + name = "Sheath" + alt_aroused = TRUE + //Vaginas /datum/sprite_accessory/vagina icon = 'modular_citadel/icons/obj/genitals/vagina_onmob.dmi' diff --git a/modular_citadel/icons/obj/genitals/breasts_onmob.dmi b/modular_citadel/icons/obj/genitals/breasts_onmob.dmi index 245cd29a533291527ee2463b26076e042784e64c..8fdea9a32d1676200489350a9305575816662ada 100644 GIT binary patch delta 9639 zcma)idpy(c`#(9oiS$mAN>h=fP>MIhbdZGBS#lVaQ)F_O)9fW3R63C}sH`V0d~79df4&I! zPut!O=~F%psPPmWKVGvlXMD{8KpNe?Ocx+8wkN(=Fe2W&~ z6B$F1-OI$2&|ON~Os3Y!TBhc*rI;}bCX3QoFIfmsA0k+?DCFtMEq=KBJ(eTx@xQ|& z;2=g*(@CR9O6+eMsb~m4PE~F3*?!ZXB?$c4&=?JIwo2XqYq6LAYcil5&*Eb=0psKIggzU_QD~%_hMY82ToV}Zl zU(imwj=D=V)Gi-`a-56@1y7u+#4f+V@^)zbA5);F+*}H$>KnQ-bvCZ2@8W_lU)-6) zruBn6K2=|N|1uzxnj*Y1F6DcoIzW0-j=kL5NvmpSHsyyRM*b?H4()+RR=N!s!p(5| z;^{Xi7p<+`qOZCGIzbJ( zJ$7PHuWH-Q*li>Be1XC^73pE{&9K6;&IyenNpG0)34TnN|I5{wVP0YkWwz zz(0YeKll&uQ7(C^lS3K^Tb^>Gq6%u|Gx8}dj-_Ony>Y{9P72E|fOvdE?18=slKip{ z*rWc7TWTWyN!kCrxISo+sj%$9N%=(Tu2-rMI+aMz%^=H`?A-w%^?Ll5$*h!&H%=JN z`3!Mn-gFfK20IK+9R$l|25?B;{CJNwOeyxcfoRBW2ERkxcI{{m}5e|pWlX`(T&1K zXTZ$rBY zp@z5aMh(C^unl7l=|(QMe+j}idoJ#BJ2)tluV+oUiqT+9C|t53QS?oLSBjEVYk2O? zF=Ct!HYp)NQqd+UzNSZfe8_qf^U^~g>$cCBy?`?%k_vrRp=<`GsG(`#Zp<^IE7I+* zH{$8Gmg3nxA~Y{_3=RE!+UGJ3uD3A%sFSE+o_UI#M42$5lvc~>Ekh^qc3``a1WlU( zPy2qM{rJq}HFrFNaoqYh8V#s{(!ZO`N7JX^GsrtI45~(yM{S4efeQxfK~S~hd*F~! z*1aBj72_L(_*vN@hOnf!WTbanJa>$PO%VLVZIf8Bq>y~Nj*Q?y%*S;(%j~(7m~+>G zZsU^sPuGK*3=`l1Wx}q+CJ+F68^f;y z_G-xfV8gGJ#F>zFPe&>2HVZf6g5T z+#G>{L`5T>o-S58?Kto`L*R8;FCvA!hjRFt+VR~y@OP8#@1{EK0vPaq#<#80g>MtA z{ID4oK30o-SuqBUcKtj~lq)|*t~=Rx5I8HbUTUfvT@vNJid;Z<*6ux#BzPqqGA1Ac zAL@?V-_v@0OX#)i$E}FIabk(pH3_;O>F0ts#iN6=>EXs}RD&w7TgZ7cOE$BL&OPZp zJwumei2jm6m(f4=uE`vcY=Z`%eUe0(p>rx@1x&{j&V*ExZNGPX1)oH=LS&6`jP$}) z=bcVekCDHxt!$I^=S9RuiSUU}sdcGzXHgM(O)?d@TmfrwXK#o^Fz~t^5tWF*G;uVL z9)huG1sI|#SO?uGeTtLrz=;oyFBX8RYk7L+3e}+<{FvVSMs?uV)wdHH^25di&V14{ zPJ-*CWbnc2rjLrM@C!XKS0=1I?j9fewhgipzAa|%-y}uMvd?wG*0E1{8@wE3q#*=q zfuiYKOQPyyH2kye)TXdZQC^?)+#I|tW;xAhvuC`(RzC8&WL}~WHOCs5p?GFA%QKw< z_~`wd7T!!K@ybVvAI$Y?u3+Cnn+P0Q?ifNj@?c?v{v(HUhP7J-h4oGS+0umU=>3W&q1rEkMG74* zYp@=NUnk=@^o<(=I5TQrKVy912?6g^^#`mJgZqj;kT1NZaFf8G_?pRdEAmDcHTpO` zVJ(lS)gOOwH7D0N0YAoiZi@=uZZ2*?CU%>4BKhzYMZ;<9htrZ+m@VX@Ta^5GP3}Mv zeySYCb!ifm^-zp^3P|zgsv7JR=sxE&oB9xk_uBomW~}>w)x5;)u{S&P@i=&s|LDYO zmacWSse#Siu;kA^K@!%IWFE&>9|Z=8uEFt?Yoa`%H)okJmm<^49TeVL#m;%pre7&* zE*%3lmgWd~cFzH^FlC9yc%v;zspvrB2caqbx7~=ry_Kx{&`}<*1z1>`0>BX90-YTO zQn*d+vQgdmw>Hz%Fh!pmhp8qF*6!-q(Y3l)oG?NAGX(=zND+DbJxhV)R+67R<|Re{ z0(%iHbZ`T{-&~_?d*g%2EVW&kl!b^lxopbuJL`Srtpdj`puNd^t2qY>Vbg1N<>|CFBzmx zX1-J8j%9hm9F2>WGP_L&`InSeL$@! z(~D(tKrJu~P%2M4OY2fQ;2?XqGk>z66lqgI$=>U?=!ZB@ z7!jC8Qtk|5n6mO(gC8}OTHmU8zoO~RY8LtJ{yDK2BfRNzneX^rmef(|V1`@K{3?il z!O4@pWdR%|IJlA6o<5jN#oqSP$;_Wq!8h}NvV;M@U;u3QpuzkYsb z%;Q}U1V^!lJ0+h2%uy0)Xz5wfWHt6*~fqfaB%P8e47`_5RQg+%Twwdd|H z#vv-|_D5~`r}2w~r`>^6qReicRc&blr8JWS?=V@(nvMQ*mv5Iv-6DcJ@YW5}A7_k0 zA+L(|0@OjF{ZP=`f}o*HW~FCby7wG3elllqJ4;a3iR~AeRlf9m*Ah`=Q^yuOq2fI| zxNu9EcTf2%*nxC77Z-kZG%uJu$lbJB_kb&jIDzC7ypS;l*jWbvD3kZezm99;<9Y{yD#I7GCenpq)$DYkvf9)tI@% z6k5+2h(H^#luf{zq8-Mj40KSTct<JA7K_uTN6PK|1Sk|k2(5mk(83luk2X0nnO zk_aKq8pSq&WGixo!se;JziuD(%`r>h=}x9Q1=p3eFYdk>y+tfsCIH07!2APxiJ?_=VS2ODE2 zq_%!$vYc8WIi2?^w~te7CCBOkNVzAFN*dCgCku>$0HHI-ou!dA0p|rfYnCzuVb6>% z-!`I(dp-(7qR`%5A|0kwL`f8{VMQW*!$JTJ*3LiDw;+rOx(8VZ2L6HJ#_dw(>&C^7 zhs;vhR_k931-;dnE1m# z?p$>5{jovCKZTzk)lExDV@x<)(zXy+-M*=odk9$33TA*P4nxJbMd|Yd%yFLB!S?z2 zNj5;K^@aQ?uOofH4x_djrPkU#4%B-$&p+-Rr@fYMY!;MN!|E^0tt->xK=hVNI8K5+ zh_W?j!NG+u<3v^2T{fwR!R^PH2q38mtaLk)StxV3^yi`>qI%5%5cNRa=kjyg9a}tJ zqg}f%7mm}HUCF_69#n{-TWi^zq4%N11cN+v)_ zm&KtQ>`6jDpgZd(5bwb^dX?d=z$Rrl%;nqJ6zowiXA&#?syk>Xb#EUtEl{nT*K1I9GTcH0;n%D53U z9qSh~ul1A;H@4%yVGMc*yE42Ya%;bB9_e3o8a3UUVE1&FB_(OX>nY+)5Sq(4Xn*Zb>I|z z&BpMt75p#oi!6U$5e3t+lNm7Ef@@6}vD~s~a?Kek=Jtw)mj3?WbHDFW?z`USUDkDb z;ic!I;`PS~b;6n7=Qi5%Q`&9&*3EM>-${G$<(CIqjz9tZuHq9s=rV7Gw7hOz4P-dn z1!-Mh$)OF2!f(ij@(ANTaS^JsfXP`r;kU|s%|bDbFc(dKKe=r=hVPxbrEJmkU4ThF zk`j2~XfBSz<(kO|LU8NmCo`+1Fsbs<7?4iaSA@N9Kj z-aM^$@8gQH{vNVaG zG(ja1aM{S355oAbJiceeVn0_c3J7aH^UqKKQ$~U)HNdAj=;6m7#i^B?g^}(W6vWkL z15J6cz_NpRzbxut3GF%nmS@rUjb+a`c6D2Gmz(D@X&iSMbgrOp|F;3J=sS^iNoSm) zzokJ=7OgOZX$8_Q47kNL9GE|tE4`+ zWJF;Ai&oX*{Ft~Jh70qUq)NVT%Ov89_^ui3)%suJWeiPYGaMkASK7^VOcUY6n)2jgPn>qZQL+B>sXV?kTK)&Lo*UaTIc%{VNJNQ39SrkTtKQ%ki8Ju%J$n*G>-)h$<*Y2v5-@!8{csF#&p`@g z#6)JmoGd}-qj#db5=gP(4EOfShExBc-v87qmH1Dx?Co#549@iS{+8;ooVxNBW$nR< z2D;CDbh(@s?)>H5Q`jM!M~j572b^L_j;bVwwrz=fjH+7; zjssz$CctK~h1O1+gYU!(kev$HBU^UpN=e0iZlblxUN=c;)&mao%eX+&tVNzmb%X@Yj?H*Ci>C!W`a(0S3|M~8-Zs^h-ztuxbf%tI$YV4J z&RX1l&(nJf7uAA;nt^ZL$S~$8V>`7nEDj_ygW`aAxH*_CzUVx=M+Bvn$P-Mo!n!5-=}YS0^T_N1l{4?BCZBvEB@ zYQSAr$ugu8?Xr3)nk0N)vRZ(F!E40#PJ-l#Z*v$+%;M*WjXetV?oQZv)R165DJo{p zg};+=3xg9}v&#To4>c}+45_;?LFz;j(Jv+qI!bFh+XSAX?~SUz1RHbGxlizEPUc55 zPc6fmFsn@&6cyqc7aOwyXgh@MWtztYY#6lx zOq%`GMYTR|G4^|ulKwe%*$)oMs~b{l-+RNoKjNY!*~91gZ6Gv^LUjqLoiQ% zhi5nipT&%79jzp0JHaRx7a9cxT=&<#ooz&`ac0yxouR^Q`sJb5X}&1UPPGT-_hdJf zWWn5CpBh~&*7W*r7G1${LWP{Xt59vRFu|vGwu0O(A1*H_-O?wUG?O`n1vf+|GYs6Q zx{t*3ML583(RP9B@RGUVurVr}GxNH|h-=+2 zN@{_)kG)i_xRDGEHR{1{#6y5ZP^~>j(Ba~7u)br{=>Zwb1(p;`F#Otg zyZ*bi5hNRTewJ?9FL>%WP*Z!ORq?toIO=BA;_Tm@`|7wJHhxS6vpYr~TDP~Qf3xznPy-+Et|0F14SdP?v|Y{u9K@eFs)-S%RK%W^VV&C)um8@e zbsqjD^pl7s8Y%nq6lJPGVBTWwIVy^K7$FnD%<`k-mk53ezCO|=wD!ev;iRvU zu~WMrj6~WoU^e@{m^7HR@Psf0A7qH=+aKE40>qV^kNHGA9?9 zR9MLwEPDmB4~u|Gy7B~%6Xr0TtUsVG&!daFqam~o_RS;dM30kZKzJ3bg=_b41)GdA zF%J^15C&0moJ7fm3KL#h0&^_;&ov7Jw@}GB_L(joxM0_}K_A|9_8V{jT04giL@Yc; zvi_8++}`Q`ao<7@^{vjo&?zOQY-@k~$c0FWm0T4?7}(8C%4LdLTqY?dwJ1?KRJVyU zf_@gOV2y(}ftsnhcAU{<&M}8MqsO8o_Xl+++U}}kb=+Rq1%%OWy!DvcJkn6wrcHz#uv+4UEd)4Fu-Ir0ev$%@AP zOSUSr1CRcXWV;V*R2mIj^2i8H0LQG_?|{thf&$51-aV|6uA$OeM!KNBE9$nO5qnhEeocWXHc40iR2hL~ zCboYq%BzB%T9oG0o-}AudUo;3_c`@%o&Os{iMJgA&beQ70xn#%M|qy5yUtPz9yO-! z-eHvZIYv|SlE$35Tb2fIwfWK-m{Yr6i_xxox39H4xBb7l2xj-q+KbSoggvuc9WV@G zL}&xhdlJ2)BeZwo->smufP{S)e~lAx;)&Vxmq)qk%^pXVjk-|T;_GpFF#p>Qhgvj` zL&a@BCjYuFhX0K7@6;}DYTg+p-_;466KDp$a;W%a@&F|w_E_KXW5OK1;VVua$z=a$ ze>47`TaF0)FSgQ9Eh;QYyu*Ze;m`jl0h&w`xe%*L&T89XGcfGo#dghM-kTpn)y$Al zw$l{dF$N&MCKM9)iQ&ouDX-8wPWm1+Wx{>ixf|)*MO2(){W774JvttBs;7qMLjMd$`)&jX4#j z$V<%LFD4DtSx0YsDwZ(Q>WHIQfCRvPI_x?sy4d)Ob$EOd%0^fUc$`n!BG^GvpXOK&0k@mzI;Us-y=ERB}jTNjSguv*4LFeAGk-iNpE z99ua5yhm4*tS}rImro%~irE(1yL%WVJ<=sONigoL{e8OBJOAhb5U8oVxTrDIkPuRq zpvULEO20NDjj29;V%cvheI^|FXHjj6+^6m9$Qx~MP4R4qF}2K{rY~LMucZ6^5dI zQJ$aN*QI ziB07iduR@LKvRDC4Hd7IdZa@?Zz)tuSoUdk+HM&U@wUZ`^!JG)fBABeee99Rd5ws; z8yaWB*M1ax&r#;YgC$xF8s@GU+!kjuXSZAl!&iSLV*bF{j#Id;128`A3D205Uf5oP zINk?=4>|fFkDG6#Wfdb_%1pVmt53QQ=wuK&{N6|_ zX0P;DLb?Yd$-*sAa@M^oDJc;dt8l;k)6aSkPfsX};E2zj=|@)5(JYZ6OK|V2bB@KPGjc1RdOLZPfKyc)j7W~L zmqin8{7<#~unSQ?1}VEt8Oa^o?b@q}81nBl25AOu#vkgBzXm!Q!RX(h-ay~n#24K z<@e6QLpCQ(;SZmv4iZ)4$GyT zboX-IK3HQoM^DbRX93*l1!No*MXqtg#7NY!-aRj@#fK)vsu0XFpf#jeCBkU}buyNV zote;92yLyC{PGO3s>)11Om#k!bms;$C1n{aEm|qAY>V#Sj1s$^wH%lZmMBALhNtW4 z(zbEg^@r=Ngzm2tt71jtsRiq~34PMm)(Hdp@oIsf#H@m@w|m!0?Qcmvf%vFRh1JuH ze#IOB7UHeNfNV@PP13SzFf(q*@C=wVS$&6>^5t6*6Y}jH96gnc%8$}L=AR}fY13eX z*n5gUInL0Nczw$(9Y5I#k8H)#b2Agdu6Ni1lOj_ii72ef5$F za8KT`Nx7U8fQc{8gkbKVfNr)Q8es?QLJQS?PJ?6et=tWV)DNE_dmJdtgay?H%2!uQ zb0ql|;bkpS88lN(<|;qR%QuiVr3?R75lB!&F&xyGcI--@d08XFee`=zA*6j zNAr6XfijbWMoJ*O?nn*Hp2WB@DBuTlw&?oJYA(Kc~T1>X?f8Q*-7(1E!eRo&Ya}=~u^*_>M{2jVL9gc0?IsMvF6|J_}be z)Q(V|PdZVJ61^5)L1w5DJb`n;(lw#LYCBz046$g@6!h}F73|U7yb_4&yvm$o0ge(( z>7`HX^0cJnsTJ)lNK%lvH%i>oQ{q}=W55&tV5L0_;H4d$^b&Ct5iM)naJ@oeW4-1s zC&02k3#0o*QIaKFhKZQ{ILWt^xO;k+-&;1AQt`_3g^RLuONcZ!*-%AV3!81Y^>3{t z_A7+LwfOhryR;=0*ttvCX2YG*Kd>`~jvKQBXNK}OD@ghXQd0J|r;nE$^^E_2{4T?^ delta 9548 zcmZvCdpwix|G!gtlk%1%73<*8K`69pSiL(+k`721l|wl!VJl`gI!MZCF^5=DQjX;? z$Bk6Z7OKT)gw1Kjmd$P3z3;rgpYQMc`#m1N{juGT>waC=>pHwn&*!xyREI~BeeyZ2 z^;7+W<6k<`($a>9hkJW_rE=1ywB)h(cj^^@+T7ZzVlS<-SNZoYZz`ynm7c|ZB*p0W zguckbb3@)eJZiV`AB6+LLlw>Pa{uo~6#NA5h>%)TpYf|q;8jZ);(miX4Y=QO|;>9@E5M3HNC4J1! z-V)uPmre4PpcH&e73(~B0ZZ;<@I0Ei5-Hf?=-@)8&aYpl(d{7H1XZEXa;8>MK5=XU z(Fl5opWq0|8}$G=xw6ebL-&-#HX3KVHH;~ih7Nd&{Mjvbwc&Y-3^Yu#U{WYF0{KTj zWSqR>ia>6{l$HHzxs-T)Rc-x(O)WSu!zM4Bm?tr-MAv8e9m@lWlV~K*RRL0cTesD& zRn{HO$h>UWhc*H7v<)?IKko_myNI9wZY3d`0(=*~@72(HWRRgdQogEnX0aQmc?OQW zPT&CRBOzn{nz?^PQL_PS4zrv4H$Tuv42NPaiTfdHIa^eT!MB=~IPIEnW$~|3*B@-m z(3o|Ny4!@HRPrnL@WJ`XLFWT8)8+7XW!YLc0Z~|XZDiGO)c`s*QJtvg%PqwX7KjWp zs7D(b3MKo6fo|5!A^e9<9yW(t1RM2OZ6u)9%v5WU+d%Z3b(d}>&e7OLG zs+$QBSp!e1khc4pbNLL1ACf(tSoOK5ylln63?}C%6l(ztjD($rcf-)p*J}A<6Syw^ z5WPJ6U5Pwv61`8ei0iQSOxc9^ny6=BPx3L;84Oq=Pq_?*uBf%1=|l?9cHXCDeqFk0*DEc$U5$}dK?>J{m6><+T#;FIauSbb*aXoh`KMh3SH zy~fxcAMv99^Z_ZZ7TLJjU{A9>G^)f5qr}0+h7|E0j9$>C{Ptb8< z_t{$2=khtn&*rC~N6}!Xsc}$~3X}k{9c}olWahL1a7n=cYr$I3h0Yejlhv(ZOy)7X zoFq75(R-mm9-{rAX10rfDZAA{ofF_h8rZo!LqmUGY+SXB({Bz zd&Bry#1`8NwT~?r0b!DW{)7IozY?};fNz4_gsY!na3|66>EbF+OemB{Ia6p_McnbW?B3oIq#CR%$H}3qfMPvh zMcsXhVMFDh>a&JFtT{2FOcwo+g863IF=zuy zH-y;82uf9=^!a2kW%F?Lsk$>s7=TV@`-kA5@mI6*l(xUHgT(Ncn2aqPsKk^e4cp7B zalS2TFa7S^I1j4F3yf-}-4(dgqViW@i6FjWgG4=g;e$f3)SJk;LB-;(~0bBwP%1{ znNtdl`u{Jl{6Muk2-K+L55kDjka_#E4kS>n8L$9V9i^A`k%42_X*HQ9-Rs)Z)ASqD z4l~FJy&Yq|?hWUv4nu_!_jb^IrWk4eqvTIGzV;$8xWN9M<4Gh<&ty4q6A_^+ydw`r zS8wG6OO=)iyGI3@O{&M(Z<<%8!7CaDncvAJJI1l|kwC`v6&0eBgbXshWKZum*qK7^>pHV#L^5} zRCEm=*aO45l)NzhK)rb}p)8W3d)3IisQV4U?@k<#A<%k?+XQrImqgtL2EX4C^an%l zB*D!8_C$h!*fmQ1s}{M&g@F~e5WJMMFGT6)Ayr*gOB@@+1x(l_v4{(sW&*2@;QC+- zKZCA`0;?tyKRT-}z*l2GanXCkzo+{E@HTLf!3_nef|gFDyS=6Pho|VFDn2(YY35Bf z?m7ewH3QeP_@F(qdcd^~`%1K9A%N0b=Vyz5LEU+g%fm_R+<Kk_VfK5kGsB7=AXR%AYkRG-f9oQ=iKbb@J>Y&D)lTqCiqx{k4E zn)!2TU}rD#wqUochqs|i4tq$c4x?Fg*YIYHL||XWJY!b$`NGZ~q3M3jfc$&&gI#5P zW=&@)58u+4^6)bOH+_G8K2v4~r*@j})eHz#jY#+GH1+cnX>(QE4RxOY>y)!r}Z1~W>9ndU#oc_ES;J}#m&-<0a? z3-E`mt>gnZRyPhm?UQpj#X*T$vG?W7g9g#k& zZgn9p;TmURr^5z+A|$%ni@Tgf)Mm+K{$caaCMnP zhq6Q5rH;XqI|@5PumF%k&U#yvg=O8{vtjsnvMAw2&71m@2x*EFhQ$8 zm<{8BnnnFkoUfeaZ4{6q;IbB&xJ@f67QPgdOgzvVF@YvVdVZdkDfT`bW8-xdM|&q8T~2kPWA zF;NC<1=&&xujJRMs^s%bIsVhK@K)`iD8wOTV6E5n)q97o`Zza!F*R%E4c0_=t`CKm zTQNx$P7t|Vaq!2cwv~6LV4kxYPVA$U>nn2keAf6Z+6x*~t(gC<<8&#t@NoN&lNrQp zbR_Trd81OCbd}YU_M^L$Kk(#<`iO!D;iMm@`8c=$kXzCI@A?~d&?SM;-m#%*3 z0NkQ6_`5bz!n==8=D^k06OvNz_JcosMT8&i>Y!L9jqU9vV(M!aS!*0zS$(+z9kT$Y zsI1RI?WaH7kJPd+tIhK2)2;;#q$%gMfv`(m>bLl~5f0^YE^?<0@_IqG;}q$#><~J7 z1Ee3Gt^3oz{khK7az!gzWDEIYw;6%du~Fd~zl&Y91p6rNH&2)Hk;RzxTQaokMT;meoJIfw{QrA+AUD6N@ow7ZH`L=QXnx&$=6O2Xz(SuSDP7VGL+-L1wq} z`#QGxfnjwU2^E!bM{KnJ-qWvP&LZT*bHZF-&3FCvVEE|%V;6iTj^ zizoGFcPR?8NC~_ZyXVG1Y9<+Fl2~dyKpNXT+-=FVagiR)B%K9jbKPHWVkeRhXUtkr zJM3dgo7is%;t353QOxYqZZ8oQJk<~y+55T(Rk9_v-qNazRSI=&BxX}Ym+8N`?@=f0 z%YvEaHs9)S=rg=&s>1lR*OANC%yU14gqqnzrZ7+I<3kHuSxH)-^PiIRwx;nusaF)$ zA3_4!ElPzaR(Q`_8n^?!q00TAmzD_c1c-u2>@HXNBb4l)%?>h?TJtLyugze^J8juV zCDAV-`X3U5D=<_b;08DHA)smPGC67ObcrlidC{Mc2*+=4ngou}dv)zi-a%im1Nd;Rs#hq>vf zCpv19QdS$bU`UBm3-{0njck$g-B% zgrt)`V{f%e zC-ppMu|L4CGH~nF19FU}q4lh~W!T;=KikR01jynPGSF#5kP7t@bZ6C|>PAc^le}#; zGJCrJ>?OKfR>Psd43!^3BNaoJP)gvA8D3!YOEacrqXfKxD&0;al^iC=W`qAHa>0iG zJ90$>TCEJt zFsprGkM?(oeEzdREV&JMK3vxgpU;!!8P8wmH3v<8gT5!{KM&EK@;QH(3(HO3ohAfr zIH^K4`4Vs@2nALWC>u7*-y|?L=mT}+HmNm!Nys7rq1fqg5l8B3le4a$WHCecGCZa? z^^N}@?BWJ-&h0}s>J}dy0BJjX^a5=WR4oSSPuacg!u#P6Qk$t%CpMQZ7)Q1y>W+j_ z@Au1lbZh(iv606kqWsy|Z6d-_gX@CmP*tNXLKdHc9m+arVSvD%%s&x^AbuLxmi$H9 zG+g4L%@MQH+|IxP>=0CKI_b~3bL%BrD`b)RUqmu(rZz2}b-a#8e)L^g9fI>`k7_we zY~7Kr?%z0yNA9KSQ|ql|As*U5eM5t)XopzDV##L1JHj1LJ)(1~@|DwBw)B0K{P|3} zi16_D<hQ?p`-+0=U(1&3l3nawoaq=DQ4xt} z$h}RXPACD*xT0Ci{l0@gc51(})U5YEd=b&OgQYmVt2WMk;>@juWdcrj!}W@3_f{im z9v=xQrZ`Z1D9fb67!X3}*`h~CQdi!tZ$t4g+>&+om<<@;qc=PN!l?J!=w0+#hu&`5 zhe<_V+cLYgEW6^L#tSLempre*P^L#AXEy2VB=e6a^!#k0F><00ZU&-qNMa!qkYSQZ zrTkwc*@)9DtZ!Lr+8SJ)G$D4>F~VSZD3qLBBYghX#=G}KhAnK8A(EV*!>rn;{}D&q zZ}aXK(W3#m)4p#6-E=+|UUnP0(W?El>|2AvN$$zMZrVefBX|!9MC+s(&PIKzizZGw zJf^{W44EZSTYk;tQ%mSjdF7^2`K!)v#xCbbO(eFk-GL@O_fZ$lcAGY}oU3_-!8bD7 zXvJ~-Nr&F=IF*#h6;l+YI*KAlRq$uWUMG;QT-ic`^z8+9bGD0GKlug+7PVXuvU~^P zf}ls~+{TjKkBrS4EBP`+s0%cHy`Vel?6nd4C7DPqzLt#b};Pneg@Upx$Xp~d&>v!MOLiv zxI`Qj6VKD+{{60DJYWeNf4PoDtmLk(#CT9RTah%vu6d8~QyJOY>ukz9Zsi>A+^Ju7 zYe+n@_R?AuNb`C@>B-ARe;^#)X4UvT&XfsYoVv;MN8cYiKeC(8J|f6QrFrvDesmiN zH*pll`f|ia38s(9CNjM89aVNiRviRT@-zP@!LHWYu^nL7L!C62d%F`O#q+Xj5gH^H27(%IOU^)^kdU z-w46mHp`fJx!s5p)PigvbNS){8j!j2a2-!Qur9S?bk~B~?>uZzJNRZR%Hrb%q3Y%a zm^}hm2q*UKlw|33k_a=3hO_GFci?3hN?euXGH@JmzeYs6X5r71GHAa;}h;(GG<|*+Sz==jn`7|?ptODrz=RA8Uizs*wOm%Nb0V8dU zW>@{q@9jUhv>-!?4zk8vZ~Y8k(er)Wv7TsbJu*Vz3bU+L=Ety0cGp!!(qr!4bFY_*LC?oF_=+A^N6m2Or$lnIpIpSBFa z%+I=W#4^%9?ZCZs4ZQ`KyK%lhV5^Sq?C-(G-TtF~Yg~LZWTnPuhMg77;HD?@CcAXD zj^-JEW^QJ}=H6yaF1FE|Cy^${n*S8VBkvWkP4_mHch=me-WXQQpx6UE?T1nC5Q+K+urC5M;UcjF$X zG@F~YT4I}9#{fkH+`_(ga4P|(s|Ea13l^5ks1oGqZ=}$QthV53Iu*mHp_vZ+d&^M^ znY9TVQa*iu;ms(=VZYG3)iu!4kPEurcCV~-PabKRnWzOmM1D4x-CG>B0b=^E6v8we zqg_(^HEimlIup>e>=D_U^*gHB_^uO?7`qJWW&Cv_DHRd3x=hTLHb@((oH0afYHymuHu{yqe zc>B;ns!~>IBgEUn5l0cyx8Kl5?whfa*6q2y^1Zb9N7%|>NH`QZrZ|0wMC*bj=as*t zN!rg6Je4*BzfNgMaxr*o*~J-0TzN?rS+V0Vo)sEO8>+V!7DcAY>XNh2&j_DP>hbMX zG&{PTH{}SvzH&Nj>X0e#9(Z9DyewpQxW~XzysO3dU&nW~mG;%&YH%8(94}-WeI`wv zlk7aEI2drvfr3^xCYY9m15O?pA+g}7b?3uxkml+c24(;ZOGy_Ws{*F=!*c$4N9fbv zw?gl<7ydFq)nL2)Zi0z{!O9QDS;)1igv$mds=Jv)abwTjXmL9s*}zu87)}^8*m=65 zlmnOA=0dMzhscxXF9#&mb>6PuXJsUfI=HBkhGn2`N7=pm^yGKHu4h_KCJ~z@-FyT% z@1AB4T)cc5<9Ug3Wrnt^u$|ywxYe}qQ-qF=lk@CBw=8YpbLse0Z$M7%T3u$R!TtXB z^1M#t27$+6S>bc?tBqG_&n^PVPzxxz&BSg25Dzd=h`z+uUUa{L+6JO7w|{LzA*3Du z2{jEdbEsU-0co3@Ezqk#^h+^+gn@{KT^g+r(n~S_;Jr@0?S)@;jv=JB^S)&dOnP!@ zTLwVpS&>?9w$%6t(7SDgH$~c7#usy|T6I1>xzz%+RMAB0W$oHvW9?M!p*zs_nUMB@ z1?Ky%T**lX&T^Ha15`Wri_+M44eH76v$dt}sY~d#MJ^R60;H+q($l7VQ@37JT{ry~ zwAH)6h$N<5XBNEMb;ahwI45y2I{*WY<)h7_;d!ufs3;f-B2YAgU`j?XUij6M=eC8w8Lt}jgk zqK@S$miPHT*eQ6c8Bn1(6)WLqhF8ed-S7F`m%;EzSUJp%od+|ePuF`A&0KLyqF`BN z>JOl$Nj=ZsIX(Akj*K2RxE9e4<3xQh@s6n0Gu=}BMMTC8Hs#6R0d=HHw;?G$QTdNI zZ+cXY{_l>A5}X=X2a9sVg9E$3h3m>sgtQLFFvo=0);r>7pF`u2qw)vzh9_x-ptLR_ z_Rk;kbm+29v~*aZK{KHL?Kyiq5EPgyet?~OnLabp21QPcyWEL_l@K&+T$jefhptcr z0`>meF_HRp_xQ8anE~ss+#Es8qt$+C!#|tH-OAH-hXF{ebHWp8#bA5DhGVBcTYl_X zr9OJaT82Pl&-h$yQi^aKf=DNMZEI$87}sMgrR2YKXFFM3`tog|(2wmuKe{ zqhg7u4oG<6qyFvq&}`0ZP5SDern$kQlp$luJPNKT?tOlw^KWqtRFPL6Vd4`7*S>+- zD&R7y=tN(WufQLEB^hYF6O*xUEv6yAU|>4gM?Dl#Jwtl8O>inA`6{u;xQt?*({Q-P zV_^C{My*OwEciBCv)WEzoKjO)3eb1Un=>0XX0huKu>&xmuOFrVChxgpb4MEfsXlhV0M?ut5 z^4eXrb?7OZQTl$g?sCDx;+@!K!;gFLl-0*^X3;|)=Zp#$y=`oALO2KUs4R?Z`{;lR z@_!lG|9Lu`g#mi0(*07{iq{gSIvFD1_I9KEaN}>U$$P&*25@lFy8P?A=Rb6OiycQ% z>XAit4l+JtXG3IoXde<- zcD4ivC`;uZ^?5^ocp(6D2Yul4kM4h!QK?TSCW4Pa)ySgfCip6(?2ijCdY-$MBip3$=L2eN2uDvZ(k#d zT3Oj(`!XVmHmG|M0pLE7)aK~uV)t)-U&=(xcT*!yvHomjW|I=*c8t5BQB;Ba>?Bv! zzKp{+B3?`_Lw2s2n?E>qR_nQEhfM6{kj-A59{OwLY7F#y#a&3A0^pA@?Xe=6Eo!%`&qEsiEIuyZyUd_u%YanAQ z86Y8|U*PV>yk(g(qd=b06-%U;EAwy(1B+@<#7P*1rPXp~l;&3ZnEvg;{JU(_vz(Qk1>NneZN)mjF=xLwH`lEC zw7@5U!gh&m;h!rULuokk@Ikj2jKk-yVLGtOCzT%$Q5mUN#d=`Z>|ej0|KnOE&!5$P zAb#`f#USa`5V|r5l323G)>;VE!1JFAF_8P{c=1)IfvA4VNt56xq`1fMGt4-s#k~zF{}JeVl&9d{jjkCkobD3@|Ok7rb#BK z@Q@KYXzhB(K=_>MN&Rt!)ok>Ww9c(@C^G*vQW>oEhz~vOqh!wEl{XLb~U^0htU;{v&9qH*8N$ z`7L7}VXNor@Ox5K@{+jxT@pW_)YmH2A&i)8 z($IOzeTlNW7V~y&`<8E{b?2WER-0~`}R2$YU)e!qQr%WRLIJy!CMXUu;A DjG3Se diff --git a/modular_citadel/icons/obj/genitals/penis_onmob.dmi b/modular_citadel/icons/obj/genitals/penis_onmob.dmi index 8beb1bb20f7e7542c12261aad37d37827a69123b..99f549024dc1a0356e599e80afb1d4a8eb1911b3 100644 GIT binary patch delta 10243 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 H82{t%Y#o3s delta 1129 zcmV-v1eW`;4eV=-0C=3Gmaz_h!XOxg=kgRpXH5&NE~ZsG zSQFz;jK!8jYf^~5zExvKW9~K>j^jK2ADGHzu`Vl_Z%c7^eekzVE~J^KB6;{aw!=g# zk+jY?ZTw6^JVrMRC((uIPZt+#@Lh9pHnXW+?RV8-B9hwo;kA-T&i(P~UgPYiG{dE- zT^5_N$}wAiRI6}Wh0`j6RuQxsr`0&E!CejRs)>v>k#RN)LM`nq-<_DYOe+!wm9M=kCP-C?7a$eBAOtU|td(P|=Z z%KM+%p30)i-ygLnI&l0){r6id0008#Nklq>_z1RiY0<_$PoPgFjl!Nt4mWot3-f(6S@!(Ny*o>jGt1f90ssI2 zfNSIay`*5!D%c)(oR211LFOQPgTeUXqsuHH$w$>20ssI2006F;w0&|A>f`BglHYD0 zW*;|yj_+64z8Exdh0#H~9~8=K^GoZQOu}#e_lCmf<@w3V{L*@sHdHEaaJ3I(d2K#g zy5#@>0001>&aK(=q#~SuR+%qW_~rQS=wVVZd)=y^)#ZzowlCg{n&bngFU}vm9o6NF zm2T*1(>z&SF@4ag4;w1Ymn*#G-ZrD`3b*cmsW)LmrTPDE_uad!;`PNx<#_-A0001% zg?`M=%h|u{E~z$OE%syjwxL0MxFZw$G1EuQVa)<+^U-8d_&iYP$LuttW^_U6AD=&- zy}t9ReXcgYq{t6#QPfkLkPO_Qmnnq+svs#YY|FGsPP^nI{E%t%6}(P;EX_+>ZeO00000 zu9+V{l7jtEUz$(*Gu`I*7mK7~(OU6;ekjlLX@92M{P6p?q+-!}!(mu|p1*4Ic~US8 z^`&_L00000*sL|?4<-GWDDBU5n_px8(CU6nl=o-4&95D~OIIDe?LAJe<}MPdF&P;oz| zck_$F{GsB0Oz-9w#qLUJKgRqb^NWh|-7~-F>hk~q007WCd#68}%y;hRaos}nEaRwR~+!Vh7CqkV@oFQo^00000NkvXXu0mjfE?Pes From 10061594d8655c09b53286b7342664d27ca8c314 Mon Sep 17 00:00:00 2001 From: QuoteFox <49098813+quotefox@users.noreply.github.com> Date: Mon, 9 Nov 2020 21:03:39 +0000 Subject: [PATCH 14/22] comment out on comd.dm comment out on comd.dm (confusing how to use condoms with extra features.) --- hyperstation/code/obj/condom.dm | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/hyperstation/code/obj/condom.dm b/hyperstation/code/obj/condom.dm index 5964c84f..d6058a9b 100644 --- a/hyperstation/code/obj/condom.dm +++ b/hyperstation/code/obj/condom.dm @@ -20,12 +20,13 @@ to_chat(user, "You unwrap the condom.") playsound(user, 'sound/items/poster_ripped.ogg', 50, 1, -1) return - if(unwrapped == 1) - new /obj/item/clothing/head/condom(usr.loc) - qdel(src) - to_chat(user, "You roll the condom out.") - playsound(user, 'sound/lewd/latex.ogg', 50, 1, -1) - return +// if(unwrapped == 1) +// new /obj/item/clothing/head/condom(usr.loc) +// qdel(src) +// to_chat(user, "You roll the condom out.") +// playsound(user, 'sound/lewd/latex.ogg', 50, 1, -1) +// return + /obj/item/condom/attack(mob/living/carbon/C, mob/living/user) //apply the johnny on another person or yourself From 640786d203d8e129f4136b6c856b1460e4effb6c Mon Sep 17 00:00:00 2001 From: QuoteFox <49098813+quotefox@users.noreply.github.com> Date: Mon, 9 Nov 2020 21:21:44 +0000 Subject: [PATCH 15/22] new size new size --- .../code/modules/arousal/organs/penis.dm | 4 ++-- .../icons/obj/genitals/penis_onmob.dmi | Bin 11737 -> 12546 bytes .../icons/obj/genitals/testicles.dmi | Bin 1241 -> 1196 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_citadel/code/modules/arousal/organs/penis.dm b/modular_citadel/code/modules/arousal/organs/penis.dm index 5a9d7fdc..816aa752 100644 --- a/modular_citadel/code/modules/arousal/organs/penis.dm +++ b/modular_citadel/code/modules/arousal/organs/penis.dm @@ -51,12 +51,12 @@ o.remove_status_effect(/datum/status_effect/chem/penis_enlarger) if(21 to 28) //If massive and due for large effects length = cached_length - size = 3 + size = 4 if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger)) o.apply_status_effect(/datum/status_effect/chem/penis_enlarger) if(28 to INFINITY) //If comical length = cached_length - size = 4 //no new sprites for anything larger yet + size = 5 if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger)) o.apply_status_effect(/datum/status_effect/chem/penis_enlarger) diff --git a/modular_citadel/icons/obj/genitals/penis_onmob.dmi b/modular_citadel/icons/obj/genitals/penis_onmob.dmi index 99f549024dc1a0356e599e80afb1d4a8eb1911b3..85ac029fe1db83aefbcb15d32be7a7796c71cab5 100644 GIT binary patch literal 12546 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 DwX%8| literal 11737 zcmaL72|QH$|35xPLrsZpNu@|iiVVq8VJalqDwWDIb5lyCktN$Oh6<%ism4AnmdY}g zkab4c!-VY2$TCBg!C+Q%erNjJ&*$Fz{onrccyydz=Y7t3zqaS|b>6Rc)G1pF8Tb}B z1Okze%%bS_+g+MMtAWJl6--iMok5^b&I5joJX0sgDd~n_a);wr z*6W7IqGh@W=ZgDzaV_%!b5;k&?=sw%Zl)5*x7a)F9>q9J`aJi@WOrXJNL7XL3 z>_S|84;S7l9NgDFZRGLvYMEdFlR0C7s*ihhPbRh}G|K#h=9$`52Sh+>>lM{~5i8E= ziVvpycCRwonG~^2Gw282`iyUDX!jp zOM&iQQKHsUa&3Ki(r~74N~ql(*Oa8C$YWirtY8Bh91bDgzUM5QUaxX?=NaGA*OIqf zb-t|Ey5Z!?_fHaEr{ilAO!<-YyUI&7<}2HE4pn|j4?7fG%=+WSA(w0;4~aLI zTCbyb=WN(wZo2vU=b;sf9ZwF{nVZ>!jeUi@XHdPY{lZZO;wT&!_dyP;!h+itS@>7!=wc*7%VVHOK|OY|>|oG5v-v?HwxNj1i` z);mig&yA_b->Y2w{ltY`r}gl3y#uGTtT;`Fpn*AclJ9m7?B08O_EEA_)71$VYQvsA z{!_OHVm*m(xz+vLpTg>W=mOiua{CwIVZ$RgKkFPlm|_xT*7=9qLG^}P&-)W3^K)J% zRA#;HYt)p6UDO)WXB@euas9IVd;RrajvjT(8nE0N=>ZEK4K`!;jug5~ZH3j0c8sfU zSM#&5P*JR%WasG~Yjpk?eTrPX#^R|A%<|&iV0_q>vz}cqKbWqqK;|(=Zv?-5yD{$! zsbiOveJ*wKJj>^0cV*j^kANKsXNEX$RR&|k$-KhNk% zyLMsa6D4Cb)~YYV<_{g^*MmZ#Y`tln+(esdEA=VD#%tA|0}@7XJif2aJ!st4H$R{q zI~C$b+J!Mu)w&At#qMX;Yu-B%qoiGB4lK+8jfy+a+|?@WZ5 zRU}z%hjHKxR8YiAyoByBH97#(*Q@zt{`EAzQNhTJ#w!d8B1?CKSklpK@OJ5F%)u(C z>G{URt2$e*SPpp?S8L{B0#B2)$*akn9ayb-IlRT;$^AZWkJ)B6j^Bm-vgzm07gLp#E)zhX zH=btEpoCMo$HN4R4kPk{g`*?oa<66LfnjbjnQ|*H7?W2?1QveF+pwb&n-fi1E?AbV zV8J%dnK*R$we7dVabQc1d_Gb3iBj;sPYi_%e1TB_-Mq;Ky>y!iE1uVghfiVg`QBZ~ zU)v(OvgEEFkU}MUGV>#-WC6@gwAu6)PK4?wT^wPV05pYo9xF&>ca_5#VIuYGqyJ;} zHkv^XjR`Ci&C1uj0Ud0E`maOUx>jdH;{;0P-=X#g1RJGhhc@(hDD(_ChrdhD`{M~(+Uab9iKs-H9Mdky62Im|I%Pu(iqEAh2~AG2NbS5YvfEF8mw6%B zQFZHn>E63l5^oVP+F`?zC*DxhwGHl75$4OYxGNumqbTD9egEEt?i%XBu&m2W#UnLM znw6DJ8T3!!w0_=hWK%^K8K#S9C+Kz`e!4R5x|XT9Mr?GHUG@fp=ObhSf4nIhljy>>gN zt%by$+5a!|4Rz!l(c4bA`$|LI?-XCvs^0<$q%%v{!g7RmZ46NIiKi?S5>j6ZLHG48 z&`)A!F)<+`D-tQ92kq@)KJy$PHg2Cra++}Eu`;P&eP1mIl>vB0<5rwGZ~fL-z)E-S zOfl{)&x<4^N^7T~sB|DDQo@=XOJLV4Y)Z^ua?{pe-GA0Oj?MWy()q;v=p)G+8qws zlW~vY0qW%?!Jc^k>q{1r@TnFDZ5`O%Dhg@&3R;B0DFGOVG1BLO9qz0HpYLhJzg;Kn z{7in-Gh~NiXgy&qta;%HTfZN;7o@FI4=^<1^Mun85(_97_HUbScnXZ;>%l{8eZ#Ng zh0-yYs0-yd1cqBI_<9E32)T4(Nvr2Xujk6Z)YW z0vY;AQ4_;&muHj-H1=A%z^yIe(NK2JN!DyT&q{VX+85z5TQEV2B6_cIs6CJRmq`0l z6uRx}RwvP|Ht(R;EkE(ltDbrYz(ZAmoHl?3ETe9S4%9EmWhPbmriadr{Q**f+X6gV zXkdYGLZy~v{|A7cK)r+bTl9NqZ2O+B)l=8qwmBD7c;(JcD}1b&cqDrSuM!6JzUc## z>T2qq8f&Nl0P5(>HzFG9*>2-7;2Y7h|?>#^g**BWD)kO2{#$0+!oN@7;5QV ziqR(sl|QJNrG*uV=EbJpcM13C z9pzvT`RdXSrKDc_%M>6x@;L3bU*FsFox`$WYG~}EyDsP*!+ze2SLYlZ-lIk5h`>}k z;RvunpG^6UNI3>hEu>54MUV*eSDXWd?=0qXw)_B%Nuuo4j-}F8PpMQ=S|h~tZ1OTb zMd8A)OaU2UY5EvY`?(cTnaokwy#FxYixGnfwwQy!BB6A|!5A1}>$rlZkQj0NgFgBg z7Z_qYSS==dFX+DPqa!g3XM;OF0sUJ`my>~I#L*#3w8bG{S}o|Wv@f}h08e#RnL`-%#H}( zGwJd(M#Talbs`19G|jd^&<+b9(hBOCJQ;l;M15;f zmXk-R7k|%gr0;oL~{#u;vDEvh`ZNM*=H@6^>wo)B^PNAp$aQ1>o z%Q*BC;>mm$;U(PO7r!bJwJ5Y=X@fy*xve^5x{C6Q_8nw9r6ZK23#(PSP&?8yQETqh zu70_&?pG>;@>{f9exI@qp_Dru5v})EMsEAc*R?#tqSi=kxV^mDbFFR!YGuAsFpEd} z@{)2z%!x6{!21=Jl}QFJ=#vidVz3B4jaE7goLjXa9=l-^jPZnxBB+e*I#ajjJz|~e zso!s}y<w&kgRhLWqsad_7TGz@)1s52iGGk@c&%Gwp!2nV$adn)*}D;hR@s=G zS<#^sTXVJot6cix^AM=<3ma5mc>O4~U!Zf-HKRQzWt5sso&}ALyd16^wBEN&Q3+*5 zXWA)KUKw!AUQrrQ2LNx{tRq$VG&)t9sPAuJf{hVowprgljUJ_YiEbKE_sz`s5a#EM z0wi=?jt%Srnqg)JMj5Xt!emA!oI&$*hbVv>{hi z62yf4HVImo29h;ouR>l31N2dt&@R)yO_)x_O$h5d zE&=?e=O&a|wgPP^2;nJ~%7kEZODWmJa#LWl%WHJ}5B1^MkHF9k)GjKtoN(>18>wO|S&OzNCnB$iOhqyG-ye34LtY8r z7E}N3d5GcGZsKs*yxkgbKq@(^5pahP7P6}QNz;!nmUmpACf#>>t(2tGjj@_~y8JL) z;R)cG@PieU9fZ3zea%inL2g+oSd={R70DG=B$6$ubZeQRr&SlNlur+7@qldY!HM_6 zb&3^sx}{$Q(%o6tC{jqhILS>Nq}0J!p}pkCG*k;N2w&<{JutDBHpg4w!5Ka!S>%2a z`q)mV>Y7pVGF&Z-c*)%>~RV`J$Ha_7$tZmseW-5c^#0Zf@l4vdk!Wpojn z8r_BzCT^6_ARh0*T|Wm5o)^{3DezPyat z<)(>{aIgq}FD{FI*3}WM%JyiN`pfhDCAujFsl3+(?Nx$77(oUnCT&q6kkZxGHCAa= zpQ33YmD_&+hVXX?aq;qY;*0FdhtLi}{Hxa$m2|Iw;LYUdJ%}RAY_jAj)Eaa@?+v^; zy{3XZHb~ZoYl!c0g>*7lr~zwoE!HZ#gj24K!H=bv_(Qr3{JSKa))_M)^R_ce@Jxfy z3Le$w>tSPvatf|OcnTeA=)+a`@&&ZgvqgvVSMZzv;AdVqy_+k%8?fXbG`YUg zIn_M*a@Pgi)mr)Zxi#3Tdr=3gmun|_RtXl{yV2uK2M!eazG{L`lHPi=w|Emc?Rpb> z_V`jG*M;wNfh&VWD-KF^hmno9Q|Z&&DX&RpC7-uYVN5N@l~INBX$aW-)#8UpWkZJguBJ|(Ke{`XgO;n|sZ$`;t zA9^XF^maaIbwM}fl4E7`6HKm1F2FK8`l4ZO{%cQa<+p`+g1dTpc8B}O;@CS4tfFe;XNCA!)B#18 zDOt=b;iVQ5hG6m36zPwT3P@UF+q4o<8D!ygZyNq6zO-vr|NCUW0LGjA!o7L~4PzWa z(ldeqFYFinVXlUD!XEAJGR?U!#5XTWpx%{p3N1A9N`W2{rdDWy(0&5+kWj-&7PR92 z^2SN<)4TyUMHms^W{kzVLqlZM-b5g@OOd(TpFrb!KLbk5bx6;Nw$;{4vQ8&E-y;I# zMJH;Dsl>%K7@?|a`O%4^SBfS+)9wFR(Dw+D4^$CMVsf#F%4__>+nt$%+rBQ~AaF&V z_vGQXdLG%PGT3@XbH?-)@qz46Fc3F_TEzr5GDA~y53ehwJcvnAc0DNS^b}#{w{)HV z-Ucfv;&zra%#p&`xVY}Tx>K@RX+`6k#@pj3gYgGNzTm(OU48S__YYW5doMl9P6iyE z`;!I2K22KeC4uOAuI2pKGXY~3pUXQ7<qqgw6)mWjr#h?zX%*^rh_fz)|v zwo1Z;qjuAIn0|&MKrX(3zu1UN4Vs>%(=U`Z`gYpn-LtB>9ZkH1E^vPBlId7xW|!n> zaMwk%d-Fa&QEXDSELPN?Uv#UKc58yyP0IigMV>qn?-`dxzGs<(a1Hu2Azbv^r#aZC z2M#ZZQs$~nmV|`kvJT=--~;%J`hx<31KCF53_7(gsg^kJfO1Y%B2(6os#Qfr-*YB0 zlYL<&{-*O5^6^CS^#xIFC;9q@bLhI?*cKuSbwmsb9foV0UVaq8GcWl;LU)PsyLmsL zx~aoNQW!ngq|%v)ydlBa#c&YS{~Wyo$p5|%eCm60*hK;J2hJXSyDgnQ5_~+u&-1yXtt|f4i;a_n zeWTKUC#0Sgz^2>OR%Xc$Rx<2Fg>E#8$1@e%ILi{msG z7ngQ~e#GHgrb;_WBVP3AyNss>n%Qc@P7GParsS9x2FZ-i7?s44{3Fzd;Td*Fr}Bl} zLTpqgkck97`&#oI&&E{U+tCUY6HW1A|D<#fuv$+8ZB56Dm2Cn0eSHeKl&k)1>vvYE2hvrN)UhE@)+ zV+lkmk&sy#w(4VJB5PNZZ&^Cwy1NBQ(J|}AETf#^AZk1iJ>s4B!bsr+O^K0 ze=`@kehvw)Bun99=ZE18mJy8%1I5d;cUC=8T87uv@6rt7CRGeNGC11Up^k#wahUaz z&}7!VZPw(^CS<8u707s$KbK|me` zDxWQXu-|^7+Xk1%8W=rJ3 z+8B3iRxm+2uf;i1#-X(hQiHbpxtIBvPzPF4mg^Qb#HY#i)6qdx@WrWos~6vGPx!g7 z?**=X6y%3I@)IakQLZ?Dcc{^-sGiS2n1l{=lxK?eXOJ`qQ1*Udsp!Xi8YS)iDfEW; zBg^t%!2ANC=CHcL(QeOxwv@N(p$OsX%$!Hjw^G_=Qj@{3fl^4~G?Kj&X> zk^;x?Ob3hBD_c8o3xD+7(|1$;V6UjT!|N;8tDbaMeSe~6?6nP+LF3im8nWk1gkAL?eWr8~|IU#toj9sGa3DB3hT6T{?EyTl`KmJV zWgB^z$I%;lRuOKOX;N1|`CK%a3mm^Z9y_>#J`Lh``-=uI zZ2fIfMeViE$mgh6rgbGRr>S5CbGl!dJ}PN+E4?vDZX!wbig*Re2*^F0PT#xvWaFrD z{KBx@{wmnmYU_!*>!s{WR4uZF-nyno@y}Ugk{<>nl2a5qaxZIe?R4%A`(S^G) zrSr`vVluX_d)fR50~)79X7D(61?v>2wDaS@rT6}xfc~bbV37nBZ;DSq0q^p0_Y<)) zFHE>w;MOf{*^89VCW#f&Pb$do#q%M{1Z*Z^mI3&pUkpmwaCq-_obU!yd0z7{?yxRz zquHN z;Pby5dFZ%(&OR3Mp;uX!QlL{166kCtw-~j)`B9|0evM5JvSzbV)b%e; z=JB2n{+Xc5O4pw{ zcy=u4n3$kAsFI14PE+yHb1j=%BEs!5G~YS?zvTTX#?-ewc`K{4E`6J_?V4@-s|MyY zQgL;QfbLPhljL*S_lRIrnQ&vl4ghLS*k5c3%KlH9Cr<)9miLO>MH}rXw3VAtGhBHp z@~7ag+h2l7{x9PP0_iDpE^_@VN0oCy1biNkJMp<*%RA+U>r%B3YbcVEz?q;iagn{! z5$|L+ii4?iL?Iq$a3IIl?vyEh^Pxyw;3p-}a9Ee4_;&#!FnK%;l}wC(myOxl!MPv< z%V-t~CJ9=VY+uwH+k+a`{YHB4G(LJHg4kF24HwKietBv^tS1|6t!KLaP&3>b10rV7 zJAgm`xTa@9j0)d`g86nB7_SUy$MIWvcQ5a5F%p*KchrNnY+|*8l;q#+D45dN0-l; zp?$HUy*Diz3a5nA&7+QTe}Ynk(U(?wt92D@-2u>5St+=?r3#+!Pr|MB|C__Ng0Yhz zV(vEB#o;cQ0H2xVaY;{uutCIMwx2028JCi1xD8_`nWJ4b9=ab4 zL>~zcGSY0k=p&K;vov@qV&p50JL0k>@u?Env$ha7ViK9epkNs>1m1cd9(cla@y{Cs zyL%&L^gE9lr{xFMh&d@hRNC!e9rnAj4K4fx4F!UU7*zj{bw$hav;PPDRHy~)65Tk= z(G`!u*WD1mZp<$B?Nex+%`TW)lGvo33h{I2NAGeRL~|e?NBm{f91`xI+5Xr6(4YU! zm;;lzKhykxdPor)Su+(rL2F!x*JX87QjymKt~vrpRhdB*nfJ`FWDq=J-7BL;s&ft?b}`dGB>d=bWE?L zIbxBxRp?&)+4scAWQZtXwRIq9Z#uFO4C!}kf2cg}R25?e$SZrbb#?mUp}M!z8@ths zf~<#7d$!PY<7{4x8tdpz774^7aMT`cwgL3@?a$4%mVYRF$;To=6=efnq>xh*u&Z~7 z^Ax04m#@K3Po4t_=3N@)ioGSi(QR@h3nk#qxSyM|A5)@#XAd^oG#Xcd9iP9f`OmXZ zMVq3#m4JHFgcu;EmxbVCr`|+cf`EExr6nsOE^@&osM__;D8SF~6MF^hrYH>L)pUnb?s;KqCsHMBEFe_O9p zwF@LN2Fe_t5Y=`YfYfh@PuMgF_FF5NbRp;*HbTDx^`Pq%nt>@!qd$1}it-IBCbrB- z!kw$@cQzSUMGAHv1l6KZ0UGlcb*fmqJjL}gC)i6n2jfAacrD@1NKNZ6;P9xAdZp}b zo^~kijyb&}>`DxZC3G#WJ{vc>P}k`CEOLAANH?gvUAW4sjKgpJ)&<98scVC^{uKvhNOf2!KRfA7Bx?%;9db~uIEdp*2; z$S3~a6ulhWSs^Mh0f?*Iq?*FOHbV0oX>!ZnE*GCY@h36&tYI)a69XYvKF9n*OiZH2$41fHD z?cOz4?EP^X+OrgJM@KtPep7?`m2jMU5OD{mDjT?7DDs;>G$y00U5!9pGt~rveJH{1 zNR5ywZn2sGqq-jqffgbV3+-5AQsZ7P-QkM*JsT4Tn|TN)I8r2B#64!tt~6c}t^nLF zv9bk=FSonzcp0C7tCH&{;&=r038(7ORZ5?P9An)6o8$~cp17^+q0P>8lVD<0z!q@x z3 z1;V774koWPXJ12j!q*fX9$d)rP`)uy+VFqs zDZ7d8C1ft}s6SidRp#pyh5m-t&JjM#pR>Yc8sq7nCqPN=9RO#*zeRSB* zU2VCu<%qn)2<>(CoNt1P>hjOC+&=2@Y?fOfwAUZJHmq_rgOQkSv{Si#{S0gP_U!zmmCEsveZ6!+|7ph-G4ORF_wJ6ivB zpPQ$m^5&JJ!=^F#TOT|i1*g%Ww>E6rp0p(qCz;f-ZEeKJjYUI~OmKtVTo04)S;&1F zvd_Q&fK5^&PK9!5s-5RxY7ve3%q#Dhct+#TWnesZ05`@#8f@Ff&reA#B5yo}wxv={ z-y=1ecLf6}V?>#Y6!yBlA|9cYd>mi;348DMRh~SR?DiSPXae1zPC~nxF0>h>;vPf2 z@At|DFFa1@(zbnZ)vcBc5FOFS9|dvNgQ{+F8@ z;z9IlwsfRSk6Abv_?OS>+w}^wHgAYeCsql^e@L-5(inS^aC+g;xVJXFbe6(OwxW>9 zA<#}}CE<)M8o`xA9HD?rN60Y@xKtLR@`;l^5V&@6m*pp@QmQi@Fk~Bqi2T00fAkS8 z?u0i_#fSo7`%9{EpltukpEB#jdyD;|z=`~V>i+xP>fmhEN_o3oM_Y+`xH1&N_`JS< l$?TSNA5rH{1K^4ppzL4UdhSC`ARxwDOLJSZ++*ml{|CIBG-dz* diff --git a/modular_citadel/icons/obj/genitals/testicles.dmi b/modular_citadel/icons/obj/genitals/testicles.dmi index 9db76b25e393b2da54c28869752451a799579915..13bb1665bdcd1633954b8f193fa4fd375f854d1c 100644 GIT binary patch delta 1143 zcmcb~xrS4*Gr-TCmrII^fq{Y7)59eQNFM;=1su#kGWXl${E3QYQvd%SIB=k?C1Dj% zjIkuhFPOpM*^M+H=laA#k@_opxeghKus*P??7DES>#ua|5?8Am;TlI{W;cYr;QjSW zY_ea|mlSWO{SLE=C#?!D&a)1UkNUZ2=G)>R_t1CzL3`GgrOg!CDbn^PW6t~y(lWY- zj|f^tX_{x@>~{8_AKy>6y`8xyc>Y6`ZR-9RYN*j)@94^- zl^n2@k#V=wYE$2U6-p3^_269rvC!J$|jlmy|o%0 zum2ujU~lUgdim=8<6oGkI4ovVTJlPmfq~h@)5S5QV$Rz+y?Kircv?7BTjsa!`+vLa z?OoqXCAk^A;`2@BD^19IldQ%Xwf0G_R6Q^p9?UOL^t*EY*`>OgEo*ZQu3D~??6LI! zrEPB{R zI#8s(<;@kA>HFUP{-^eP`mfE5zqnqO?1<}H_eJy=mu15whu8jW>y94iXIlMFWD@U| zruw6CoD06)=jGsAQ?)Ylq=Powj;~%!TkSjhs~4nQShU%CU-ji+4b~UC_AU4K4g1}0 zc62gN#Mh*LIj5q4QVH#28@@siz8v7*H)p1=KPx5o$zfxyja?YtS zRNvH5`-a2o=daV5w*vikwqa6&;x?v`U(bN&(0b84928y4>p^?!=>?mtR3 zz8P18FADMM1>3MFIvf^V_%8mfdhg`r?-g2rp<-JfesohO-=zA!3myA8w$%BF|G3UE zKbuqc*WE)?`0Jft&j0a9bN+-2OXmCkboT$%e0~)uX92;1%7i+G&&;#I-v4<&`NZyT-z&}A{x-%W+>}4TJPpLSA%B7u z%m9fj``c)fa0|kS(FZ94$<=@uoIq`Vn*Y`Ujk9>dZKR){{#!w!17x_TtDnm{r-UW| D98MyM delta 1188 zcmV;V1Y7&83E2rDiBL{Q4GJ0x0000DNk~Le0001>0001h2m=5B0K2`CDUl&I8UO&m zz`&B_q1ONa00DGTPE!Ct=GbNc006X+aTI^ku?oW=5C-5`pF)zkrBT-|C813O)?cq&h1Y8*%6LWp>uAQYS#^dYTPoIU*Tgr)x7*#~sv1bsy(l1>zz=>6o7bMG7^bCAkGdIx_Z zoNCb+aHOzTLJ4~%l(4tKNN==_mV^GJQHrLkzyI$8US<=v{NNVf000A&Nkl)TK`4=AjMol3t2-G;xl(l;z$LDlMkEr6M3wXaW%#A_P(MFP z(Fif$1!WF`$$uzi2`Ge^AA(vFah-pU$p-)h07O8{4>2tl5a%QFZG8`b1;qSc1sFp1 z8esCldOqzrd}0AH|2>G7C46+M>$(@sN9B6}_=sSa?1!Kyd;}(f24o1idVtQKoJNX1IXrY00cqI4>1Y~C=&41F@$WsGvDVB1LS;L-CjNJDyIP3w(Ec3h1qO= zuN*!F5c5NMxX7UbN?;;}p#=@7&E@y4$M+M7>eKvp`QbH?1SZ79z>CHw@_XY!eF(Al z`VlbV@5;kwKy4obF9x5;@9l>_fb9Ml5%aeaFTc4aCcn4E``+)9{qpKTyM3xJ5{X12 zkw_#GmDLE!@Jnl)w4Np!A?AO(pv*xq`QtQM0tzAKhaeclbv`B^0KlDyfS4a*G#3!( zBlB&24}b;4{9gqa!Wk3;MDk~IbXn{A+!!dpdGUnUWypW#JM(=GF+k3@ zF?x3+5r8(^yihmv)~z3J=%ZOW)gOpxMc&~D&p=%7A0&lgp{Qs0GWrM4 z0Ae>r3SdtE;5k5K>N^0I>K_b3)*sj7Pag;NbxQRQdSUC2$LW8Cm~H}Kq5i=Q@RKkF zuw4J36T1GGa*E6K4?3aik101vx&A>9h^;@SOf%*B2R$IR{+KjT7waDkgvk11;-9)w z{ey4B Date: Mon, 9 Nov 2020 21:29:00 +0000 Subject: [PATCH 16/22] Revert "new size" This reverts commit 640786d203d8e129f4136b6c856b1460e4effb6c. --- .../code/modules/arousal/organs/penis.dm | 4 ++-- .../icons/obj/genitals/penis_onmob.dmi | Bin 12546 -> 11737 bytes .../icons/obj/genitals/testicles.dmi | Bin 1196 -> 1241 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_citadel/code/modules/arousal/organs/penis.dm b/modular_citadel/code/modules/arousal/organs/penis.dm index 816aa752..5a9d7fdc 100644 --- a/modular_citadel/code/modules/arousal/organs/penis.dm +++ b/modular_citadel/code/modules/arousal/organs/penis.dm @@ -51,12 +51,12 @@ o.remove_status_effect(/datum/status_effect/chem/penis_enlarger) if(21 to 28) //If massive and due for large effects length = cached_length - size = 4 + size = 3 if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger)) o.apply_status_effect(/datum/status_effect/chem/penis_enlarger) if(28 to INFINITY) //If comical length = cached_length - size = 5 + size = 4 //no new sprites for anything larger yet if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger)) o.apply_status_effect(/datum/status_effect/chem/penis_enlarger) diff --git a/modular_citadel/icons/obj/genitals/penis_onmob.dmi b/modular_citadel/icons/obj/genitals/penis_onmob.dmi index 85ac029fe1db83aefbcb15d32be7a7796c71cab5..99f549024dc1a0356e599e80afb1d4a8eb1911b3 100644 GIT binary patch literal 11737 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 literal 12546 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 DwX%8| diff --git a/modular_citadel/icons/obj/genitals/testicles.dmi b/modular_citadel/icons/obj/genitals/testicles.dmi index 13bb1665bdcd1633954b8f193fa4fd375f854d1c..9db76b25e393b2da54c28869752451a799579915 100644 GIT binary patch delta 1188 zcmV;V1Y7&83E2rDiBL{Q4GJ0x0000DNk~Le0001>0001h2m=5B0K2`CDUl&I8UO&m zz`&B_q1ONa00DGTPE!Ct=GbNc006X+aTI^ku?oW=5C-5`pF)zkrBT-|C813O)?cq&h1Y8*%6LWp>uAQYS#^dYTPoIU*Tgr)x7*#~sv1bsy(l1>zz=>6o7bMG7^bCAkGdIx_Z zoNCb+aHOzTLJ4~%l(4tKNN==_mV^GJQHrLkzyI$8US<=v{NNVf000A&Nkl)TK`4=AjMol3t2-G;xl(l;z$LDlMkEr6M3wXaW%#A_P(MFP z(Fif$1!WF`$$uzi2`Ge^AA(vFah-pU$p-)h07O8{4>2tl5a%QFZG8`b1;qSc1sFp1 z8esCldOqzrd}0AH|2>G7C46+M>$(@sN9B6}_=sSa?1!Kyd;}(f24o1idVtQKoJNX1IXrY00cqI4>1Y~C=&41F@$WsGvDVB1LS;L-CjNJDyIP3w(Ec3h1qO= zuN*!F5c5NMxX7UbN?;;}p#=@7&E@y4$M+M7>eKvp`QbH?1SZ79z>CHw@_XY!eF(Al z`VlbV@5;kwKy4obF9x5;@9l>_fb9Ml5%aeaFTc4aCcn4E``+)9{qpKTyM3xJ5{X12 zkw_#GmDLE!@Jnl)w4Np!A?AO(pv*xq`QtQM0tzAKhaeclbv`B^0KlDyfS4a*G#3!( zBlB&24}b;4{9gqa!Wk3;MDk~IbXn{A+!!dpdGUnUWypW#JM(=GF+k3@ zF?x3+5r8(^yihmv)~z3J=%ZOW)gOpxMc&~D&p=%7A0&lgp{Qs0GWrM4 z0Ae>r3SdtE;5k5K>N^0I>K_b3)*sj7Pag;NbxQRQdSUC2$LW8Cm~H}Kq5i=Q@RKkF zuw4J36T1GGa*E6K4?3aik101vx&A>9h^;@SOf%*B2R$IR{+KjT7waDkgvk11;-9)w z{ey4B#ua|5?8Am;TlI{W;cYr;QjSW zY_ea|mlSWO{SLE=C#?!D&a)1UkNUZ2=G)>R_t1CzL3`GgrOg!CDbn^PW6t~y(lWY- zj|f^tX_{x@>~{8_AKy>6y`8xyc>Y6`ZR-9RYN*j)@94^- zl^n2@k#V=wYE$2U6-p3^_269rvC!J$|jlmy|o%0 zum2ujU~lUgdim=8<6oGkI4ovVTJlPmfq~h@)5S5QV$Rz+y?Kircv?7BTjsa!`+vLa z?OoqXCAk^A;`2@BD^19IldQ%Xwf0G_R6Q^p9?UOL^t*EY*`>OgEo*ZQu3D~??6LI! zrEPB{R zI#8s(<;@kA>HFUP{-^eP`mfE5zqnqO?1<}H_eJy=mu15whu8jW>y94iXIlMFWD@U| zruw6CoD06)=jGsAQ?)Ylq=Powj;~%!TkSjhs~4nQShU%CU-ji+4b~UC_AU4K4g1}0 zc62gN#Mh*LIj5q4QVH#28@@siz8v7*H)p1=KPx5o$zfxyja?YtS zRNvH5`-a2o=daV5w*vikwqa6&;x?v`U(bN&(0b84928y4>p^?!=>?mtR3 zz8P18FADMM1>3MFIvf^V_%8mfdhg`r?-g2rp<-JfesohO-=zA!3myA8w$%BF|G3UE zKbuqc*WE)?`0Jft&j0a9bN+-2OXmCkboT$%e0~)uX92;1%7i+G&&;#I-v4<&`NZyT-z&}A{x-%W+>}4TJPpLSA%B7u z%m9fj``c)fa0|kS(FZ94$<=@uoIq`Vn*Y`Ujk9>dZKR){{#!w!17x_TtDnm{r-UW| D98MyM From 906d23f7ccd2455f36e98d09d16497c233fd580c Mon Sep 17 00:00:00 2001 From: Dip Date: Mon, 9 Nov 2020 19:51:30 -0300 Subject: [PATCH 17/22] More feedback for having your laws changed --- code/modules/mob/living/silicon/laws.dm | 3 ++- hyperstation/sound/misc/ai_laws_update.ogg | Bin 0 -> 9192 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 hyperstation/sound/misc/ai_laws_update.ogg diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm index acaee05c..c0dc46bd 100644 --- a/code/modules/mob/living/silicon/laws.dm +++ b/code/modules/mob/living/silicon/laws.dm @@ -8,7 +8,8 @@ /mob/living/silicon/proc/post_lawchange(announce = TRUE) throw_alert("newlaw", /obj/screen/alert/newlaw) if(announce && last_lawchange_announce != world.time) - to_chat(src, "Your laws have been changed.") + to_chat(src, "Your laws have been changed.") + SEND_SOUND(src, 'hyperstation/sound/misc/ai_laws_update.ogg',) addtimer(CALLBACK(src, .proc/show_laws), 0) last_lawchange_announce = world.time diff --git a/hyperstation/sound/misc/ai_laws_update.ogg b/hyperstation/sound/misc/ai_laws_update.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5eaaf7cbe44522ac775f843c0eecfd0df8f9fec3 GIT binary patch literal 9192 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 Date: Mon, 9 Nov 2020 19:54:01 -0300 Subject: [PATCH 18/22] extra , fuck --- code/modules/mob/living/silicon/laws.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm index c0dc46bd..f84635e1 100644 --- a/code/modules/mob/living/silicon/laws.dm +++ b/code/modules/mob/living/silicon/laws.dm @@ -9,7 +9,7 @@ throw_alert("newlaw", /obj/screen/alert/newlaw) if(announce && last_lawchange_announce != world.time) to_chat(src, "Your laws have been changed.") - SEND_SOUND(src, 'hyperstation/sound/misc/ai_laws_update.ogg',) + SEND_SOUND(src, 'hyperstation/sound/misc/ai_laws_update.ogg') addtimer(CALLBACK(src, .proc/show_laws), 0) last_lawchange_announce = world.time From eee8867076df9bf68e2a5e0f7d2705f8cea1b273 Mon Sep 17 00:00:00 2001 From: Dip Date: Mon, 9 Nov 2020 20:19:29 -0300 Subject: [PATCH 19/22] big bold --- code/modules/mob/living/silicon/laws.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm index f84635e1..0b56a058 100644 --- a/code/modules/mob/living/silicon/laws.dm +++ b/code/modules/mob/living/silicon/laws.dm @@ -8,7 +8,7 @@ /mob/living/silicon/proc/post_lawchange(announce = TRUE) throw_alert("newlaw", /obj/screen/alert/newlaw) if(announce && last_lawchange_announce != world.time) - to_chat(src, "Your laws have been changed.") + to_chat(src, "Your laws have been changed.") SEND_SOUND(src, 'hyperstation/sound/misc/ai_laws_update.ogg') addtimer(CALLBACK(src, .proc/show_laws), 0) last_lawchange_announce = world.time From 8ee1836b40ecca489da3f9a8a36cc87c6900abba Mon Sep 17 00:00:00 2001 From: QuoteFox <49098813+quotefox@users.noreply.github.com> Date: Tue, 10 Nov 2020 03:13:05 +0000 Subject: [PATCH 20/22] fix penis sprite fix penis sprite --- .../icons/obj/genitals/penis_onmob.dmi | Bin 11737 -> 11657 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/modular_citadel/icons/obj/genitals/penis_onmob.dmi b/modular_citadel/icons/obj/genitals/penis_onmob.dmi index 99f549024dc1a0356e599e80afb1d4a8eb1911b3..cf2e25f3bb0183356d2681d1cf82370d2ababdb7 100644 GIT binary patch delta 5516 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 delta 5585 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

9N4z_YxB=X%mlSh^%G$} z|0lEYeg0GstZgYrOC$Q7uw~?PaajX zf#)R?i!R6726@=Z?n)XNJz%%jB#cY05KGIfp1heZ{krk%10OVU%7e{|n*rHLu zJ?}7}eclR#!HIEY6X_j}4OF|>w?cLq2$D(W9!{#npWDG8<6g+H|(tG zpS8#U8br{p{lp_oFZ5Lg%n^(vWp?aexLHMC>0vnbKSF)PhfEgD!9Y;YgEjd5THLfm zSC5Tdj$Aqa-v}Gamo2ejEuhq0;alSWx4w{huw(r}0}j94v1@Uz5`4}+2szjbN%j8f%BF1MFWj1fcDSaPf2=Lyk= z{6*hZ$hY()X;^pccX(PDUB5IkqQLSlZ`b(WkZywshX!%56D;}PU&Z`SEx|?Ing6jV zV|J0SY*#A5X8(70;QfMl@P1<+DbMaHr@EOU%;-xM?9ivp{yKU^>8`{496+9p1MobK$Cw2et7#Qp;E~8v|*Qu=Tx$K>txk&rkk; zmzU8SH@2s&B~ip!uLvxyyL@Pb9}7NQ(6=0I_r6u(tMsj@&YH9P6v9;dX5=!QZH`a1jHG- zm0YQYw!WKKlK9l30$w=z=k3F=0q)xz?v#SCI`^1vjyC@HC2CGJ0}$pL*G7mtte>C= zx(M#>wV8H^t9egY$4MX&16dROc}d^3y2kKIp@Tt_{c4Ztc^bf2M4AOUd-O*gs~S^y zu5fYAl!rGyhC)h>YiJMc3vr7r&Y$sILg`b^^_+jRK9iOPO?DFX z;yIno?;L89NY%)%u@Gq@Bo;o_;(CmLdX=Bew7Yx)R!FXks-7}&#Ir+s_v@RQac7+G= zXTm0#k@qpYc?PhsxTo3%d^fSXtk%8RXZsnruwC}hm1u(EkF1A%c(=KedbbQEF_{ZP_9I!)_Q|99l=i%P&fqNEQ@X%mt!KQnVhb*rB>I?ZWAk(%<1GsM;OMUwr zS(3<0DC5W!!duZBY_|M`k>`iYfv+9>4>LrlHf2Rp zCfvH;>#euHN_ z>gu6nBXrG}#7(vgP1ArAuHel}*@??>XKh18q^+xOV#H$Iiv-PP?5?69qHgB}H(5EVXTZq801x62j3TJ+2X*p!Ma3E=Zyj)NuASb|PJgQd!=pTTqO`6DN znWIyZmFZUX3#+!Lw70F=u9W&_qYhw*T>Jg#uwybM_*IBf(J_2n@EU`S^mS=~3cY>9 z4~Zi|B3n$hK5b;SndKW)b1^jQrnmZDdlef($&y&Qe8Il zd>w-O4sLR0KK{Jp{70J%;EwX8Ydu=z`8zyZ@tCsbwNHjs5#S#67Tq-l-1~z=nZo>I z_`Js~boSC;lBH|};`-i9o5%^pg*7zTs#*^Fu%^abylo;YXRJMX6ff4Up=B~^6ysl2 z1$u+rZFFEyf-;c$%&mtb(Ena&sNjjIgNH2XfP+gj{22|P7BM*}Ev}7(EkIS@J#7s| z{~$6w{6^U*!(FjRtvzfosXAeu4z|AePHxNVNq@0 zwXUu3am~u5Tl`1c7zIED4(0Hxb!6GhI%H-9*s<9LI%@_YBj2`py~>S-mOgMCc6N8l IJAjY>KOvvvGXMYp From 6eebc1d6490f54cf496e32f75b5d461a460aa1ba Mon Sep 17 00:00:00 2001 From: Dip Date: Tue, 10 Nov 2020 01:52:06 -0300 Subject: [PATCH 21/22] Typing Indicators --- code/__DEFINES/layers.dm | 5 +- code/__DEFINES/mobs.dm | 2 + code/controllers/subsystem/input.dm | 7 +- code/modules/keybindings/bindings_living.dm | 2 +- .../mob/living/carbon/human/species.dm | 3 + .../living/carbon/human/typing_indicator.dm | 2 + code/modules/mob/living/living_defines.dm | 2 + code/modules/mob/living/living_movement.dm | 2 + code/modules/mob/mob_defines.dm | 15 ++++- code/modules/mob/say.dm | 63 +++++++++++++----- code/modules/mob/say_vr.dm | 3 - code/modules/mob/typing_indicator.dm | 56 ++++++++++++++++ icons/mob/talk.dmi | Bin 5989 -> 7918 bytes tgstation.dme | 4 +- 14 files changed, 140 insertions(+), 26 deletions(-) create mode 100644 code/modules/mob/living/carbon/human/typing_indicator.dm create mode 100644 code/modules/mob/typing_indicator.dm diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 884a1f31..4598932b 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -66,8 +66,9 @@ #define SPACEVINE_LAYER 4.8 #define SPACEVINE_MOB_LAYER 4.9 //#define FLY_LAYER 5 //For easy recordkeeping; this is a byond define -#define GASFIRE_LAYER 5.05 -#define RIPPLE_LAYER 5.1 +#define ABOVE_FLY_LAYER 5.1 +#define GASFIRE_LAYER 5.2 +#define RIPPLE_LAYER 5.3 #define GHOST_LAYER 6 #define LOW_LANDMARK_LAYER 9 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 8d50a151..49f2307c 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -272,3 +272,5 @@ #define PULL_PRONE_SLOWDOWN 0.6 #define HUMAN_CARRY_SLOWDOWN 0 + +#define TYPING_INDICATOR_TIMEOUT 10 MINUTES diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm index 221d04da..163d9475 100644 --- a/code/controllers/subsystem/input.dm +++ b/code/controllers/subsystem/input.dm @@ -34,9 +34,10 @@ SUBSYSTEM_DEF(input) "O" = "ooc", "Ctrl+O" = "looc", "T" = "say", - "Ctrl+T" = "whisper", + "Ctrl+T" = "say_indicator", + "Y" = "whisper", "M" = "me", - "Ctrl+M" = "subtle", + "Ctrl+M" = "me_indicator", "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs "Any" = "\"KeyDown \[\[*\]\]\"", "Any+UP" = "\"KeyUp \[\[*\]\]\"", @@ -50,7 +51,9 @@ SUBSYSTEM_DEF(input) "Tab" = "\".winset \\\"mainwindow.macro=old_default input.focus=true input.background-color=[COLOR_INPUT_ENABLED]\\\"\"", "O" = "ooc", "T" = "say", + "Ctrl+T" = "say_indicator", "M" = "me", + "Ctrl+M" = "me_indicator", "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs "Any" = "\"KeyDown \[\[*\]\]\"", "Any+UP" = "\"KeyUp \[\[*\]\]\"", diff --git a/code/modules/keybindings/bindings_living.dm b/code/modules/keybindings/bindings_living.dm index 241bc15b..7ae8b996 100644 --- a/code/modules/keybindings/bindings_living.dm +++ b/code/modules/keybindings/bindings_living.dm @@ -4,4 +4,4 @@ resist() return - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index ccd5ac5d..90cf2a9e 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -85,6 +85,9 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/icon_limbs //Overrides the icon used for the limbs of this species. Mainly for downstream, and also because hardcoded icons disgust me. Implemented and maintained as a favor in return for a downstream's implementation of synths. + /// Our default override for typing indicator state + var/typing_indicator_state + /////////// // PROCS // /////////// diff --git a/code/modules/mob/living/carbon/human/typing_indicator.dm b/code/modules/mob/living/carbon/human/typing_indicator.dm new file mode 100644 index 00000000..16ed9579 --- /dev/null +++ b/code/modules/mob/living/carbon/human/typing_indicator.dm @@ -0,0 +1,2 @@ +/mob/living/carbon/human/get_typing_indicator_icon_state() + return dna?.species?.typing_indicator_state || ..() diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 9d346a44..7a6ea95e 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -5,6 +5,8 @@ hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD) pressure_resistance = 10 + typing_indicator_enabled = TRUE + var/resize = 1 //Badminnery resize var/lastattacker = null var/lastattackerckey = null diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 37769ba5..5600764e 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -1,6 +1,8 @@ /mob/living/Moved() . = ..() update_turf_movespeed(loc) + //Hide typing indicator if we move. + clear_typing_indicator() if(is_shifted) is_shifted = FALSE pixel_x = get_standard_pixel_x_offset(lying) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 61b8da65..a5edbb0d 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -126,4 +126,17 @@ ///Whether the mob is updating glide size when movespeed updates or not - var/updating_glide_size = TRUE \ No newline at end of file + var/updating_glide_size = TRUE + + var/flavor_text = "" + var/flavor_text_2 = "" //version of the above that only lasts for the current round. + + ///////TYPING INDICATORS/////// + /// Set to true if we want to show typing indicators. + var/typing_indicator_enabled = FALSE + /// Default icon_state of our typing indicator. Currently only supports paths (because anything else is, as of time of typing this, unnecesary. + var/typing_indicator_state = /obj/effect/overlay/typing_indicator + /// The timer that will remove our indicator for early aborts (like when an user finishes their message) + var/typing_indicator_timerid + /// Current state of our typing indicator. Used for cut overlay, DO NOT RUNTIME ASSIGN OTHER THAN FROM SHOW/CLEAR. Used to absolutely ensure we do not get stuck overlays. + var/mutable_appearance/typing_indicator_current diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 4d338dd3..bb51e514 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -1,17 +1,60 @@ //Speech verbs. -/mob/verb/say_verb(message as text) - set name = "Say" +// the _keybind verbs uses "as text" versus "as text|null" to force a popup when pressed by a keybind. +/mob/verb/say_typing_indicator() + set name = "say_indicator" + set hidden = TRUE set category = "IC" + display_typing_indicator() + var/message = input(usr, "", "say") as text|null + // If they don't type anything just drop the message. + clear_typing_indicator() // clear it immediately! + if(!length(message)) + return + return say_verb(message) + +/mob/verb/say_verb(message as text) + set name = "say" + set category = "IC" + if(!length(message)) + return if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, "Speech is currently admin-disabled.") return - if(message) - say(message) + clear_typing_indicator() // clear it immediately! + say(message) + +/mob/verb/me_typing_indicator() + set name = "me_indicator" + set hidden = TRUE + set category = "IC" + display_typing_indicator() + var/message = input(usr, "", "me") as message|null + // If they don't type anything just drop the message. + clear_typing_indicator() // clear it immediately! + if(!length(message)) + return + return me_verb(message) + +/mob/verb/me_verb(message as message) + set name = "me" + set category = "IC" + if(!length(message)) + return + if(GLOB.say_disabled) //This is here to try to identify lag problems + to_chat(usr, "Speech is currently admin-disabled.") + return + + message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) + clear_typing_indicator() // clear it immediately! + + usr.emote("me",1,message,TRUE) /mob/verb/whisper_verb(message as text) set name = "Whisper" set category = "IC" + if(!length(message)) + return if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, "Speech is currently admin-disabled.") return @@ -20,18 +63,6 @@ /mob/proc/whisper(message, datum/language/language=null) say(message, language) //only living mobs actually whisper, everything else just talks -/mob/verb/me_verb(message as message) - set name = "Me" - set category = "IC" - - if(GLOB.say_disabled) //This is here to try to identify lag problems - to_chat(usr, "Speech is currently admin-disabled.") - return - - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - - usr.emote("me",1,message,TRUE) - /mob/proc/say_dead(var/message) var/name = real_name var/alt_name = "" diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index 3772dae5..957ea6c8 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -1,8 +1,6 @@ ////////////////////////////////////////////////////// ////////////////////SUBTLE COMMAND//////////////////// ////////////////////////////////////////////////////// -/mob - var/flavor_text = "" //tired of fucking double checking this /mob/proc/update_flavor_text() set src in usr @@ -54,7 +52,6 @@ proc/get_top_level_mob(var/mob/S) message = null mob_type_blacklist_typecache = list(/mob/living/brain) - /datum/emote/living/subtle/proc/check_invalid(mob/user, input) . = TRUE if(copytext(input,1,5) == "says") diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm new file mode 100644 index 00000000..0558ed0b --- /dev/null +++ b/code/modules/mob/typing_indicator.dm @@ -0,0 +1,56 @@ +/// state = overlay/image/object/type/whatever add_overlay will accept +GLOBAL_LIST_EMPTY(typing_indicator_overlays) + +/// Fetches the typing indicator we'll use from GLOB.typing_indicator_overlays +/mob/proc/get_indicator_overlay(state) + . = GLOB.typing_indicator_overlays[state] + if(.) + return + // doesn't exist, make it and cache it + if(ispath(state)) + . = GLOB.typing_indicator_overlays[state] = state + // We only support paths for now because anything else isn't necessary yet. + +/// Gets the state we will use for typing indicators. Defaults to src.typing_indicator_state +/mob/proc/get_typing_indicator_icon_state() + return typing_indicator_state + +/// Generates the mutable appearance for typing indicator. Should prevent stuck overlays. +/mob/proc/generate_typing_indicator() + var/state = get_typing_indicator_icon_state() + if(ispath(state)) + var/atom/thing = new state(null) + var/mutable_appearance/generated = new(thing) + return generated + else + CRASH("Unsupported typing indicator state: [state]") + +/** + * Displays typing indicator. + * @param timeout_override - Sets how long until this will disappear on its own without the user finishing their message or logging out. Defaults to src.typing_indicator_timeout + * @param state_override - Sets the state that we will fetch. Defaults to src.get_typing_indicator_icon_state() + * @param force - shows even if src.typing_indcator_enabled is FALSE. + */ +/mob/proc/display_typing_indicator(timeout_override = TYPING_INDICATOR_TIMEOUT, state_override = generate_typing_indicator(), force = FALSE) + if((!typing_indicator_enabled && !force) || typing_indicator_current) + return + typing_indicator_current = state_override + add_overlay(state_override) + typing_indicator_timerid = addtimer(CALLBACK(src, .proc/clear_typing_indicator), timeout_override, TIMER_STOPPABLE) +/** + * Removes typing indicator. + */ +/mob/proc/clear_typing_indicator() + cut_overlay(typing_indicator_current) + typing_indicator_current = null + if(typing_indicator_timerid) + deltimer(typing_indicator_timerid) + typing_indicator_timerid = null + +/// Default typing indicator +/obj/effect/overlay/typing_indicator + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + icon = 'icons/mob/talk.dmi' + icon_state = "normal_typing" + appearance_flags = RESET_COLOR | TILE_BOUND | PIXEL_SCALE + layer = ABOVE_FLY_LAYER diff --git a/icons/mob/talk.dmi b/icons/mob/talk.dmi index c85d9cef6dbfdea474c12cb2d3411580e1376dbc..4b66afcc86c12b39954995f31338724833ef8229 100644 GIT binary patch literal 7918 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 La=84^`Ro4y-pfum literal 5989 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 Date: Mon, 9 Nov 2020 23:03:12 -0800 Subject: [PATCH 22/22] Funny-character-bus-code This little pull is litterally a pull for a single character I'd like to bus, basicly a walking chem dispenser, so lets go! --- .../projectiles/ammunition/special/syringe.dm | 23 +++ .../modules/projectiles/guns/misc/chem_gun.dm | 61 ++++++- .../projectile/bullets/dart_syringe.dm | 7 + .../reagent_containers/Chemical_tongue.dm | 131 ++++++++++++++ .../reagents/reagent_containers/hypospray.dm | 74 ++++++++ .../modules/spells/spell_types/adminbussed.dm | 171 ++++++++++++++++++ code/modules/surgery/organs/augments_arms.dm | 7 + tgstation.dme | 3 +- 8 files changed, 475 insertions(+), 2 deletions(-) create mode 100644 code/modules/reagents/reagent_containers/Chemical_tongue.dm create mode 100644 code/modules/spells/spell_types/adminbussed.dm diff --git a/code/modules/projectiles/ammunition/special/syringe.dm b/code/modules/projectiles/ammunition/special/syringe.dm index 10e44028..e97f7d18 100644 --- a/code/modules/projectiles/ammunition/special/syringe.dm +++ b/code/modules/projectiles/ammunition/special/syringe.dm @@ -76,3 +76,26 @@ if(S.emptrig == TRUE) var/obj/item/projectile/bullet/dart/syringe/dart/D = BB D.emptrig = TRUE + +//Chemlight was here, adding dumb bussing things + +/obj/item/ammo_casing/chemgun_debug + name = "dart synthesiser" + desc = "A high-power spring, linked to an energy-based dart synthesiser." + projectile_type = /obj/item/projectile/bullet/dart/syringe/debug + firing_effect_type = null + +/obj/item/ammo_casing/chemgun_debug/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + if(!BB) + return + if(istype(loc, /obj/item/gun/chem/debug)) + var/obj/item/gun/chem/debug/CGD = loc + if(CGD.syringes_left <= 0) + return + if(!CGD.infinite) + CGD.reagents.trans_to(BB, 10) + else + CGD.reagents.copy_to(BB, 10) + BB.name = "chemical dart" + CGD.syringes_left-- + ..() \ No newline at end of file diff --git a/code/modules/projectiles/guns/misc/chem_gun.dm b/code/modules/projectiles/guns/misc/chem_gun.dm index 9f8e92a8..234c8d0c 100644 --- a/code/modules/projectiles/guns/misc/chem_gun.dm +++ b/code/modules/projectiles/guns/misc/chem_gun.dm @@ -43,4 +43,63 @@ syringes_left++ if(chambered && !chambered.BB) chambered.newshot() - last_synth = world.time \ No newline at end of file + last_synth = world.time + +//Chemlight was here, adding dumb busing things + +/obj/item/gun/chem/debug + name = "experimental reagent gun" + desc = "a reagent gun seemingly made to be a part of the user, suggesting the individual generates reagents in their body for it to work." + icon_state = "syringe_pistol" + item_state = "gun" //Smaller inhand + suppressed = TRUE //Softer fire sound + can_unsuppress = FALSE //Permanently silenced + time_per_syringe = 150 + syringes_left = 6 + max_syringes = 6 + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + var/infinite = FALSE + +/obj/item/gun/chem/debug/Initialize() + . = ..() + chambered = new /obj/item/ammo_casing/chemgun_debug(src) + START_PROCESSING(SSobj, src) + create_reagents(100, OPENCONTAINER | NO_REACT) + +/obj/item/gun/chem/debug/Destroy() + . = ..() + STOP_PROCESSING(SSobj, src) + +/obj/item/gun/chem/debug/attack_self(mob/user) + var/list/reagent_ids = sortList(GLOB.chemical_reagents_list) + var/choose_operation = input(user, "Select an option", "Reagent fabricator", "cancel") in list("Select reagent", "Enable production", "Cancel") + if (choose_operation == "Select reagent") + reagents.clear_reagents() + var/chosen_reagent + switch(alert(usr, "Choose a method.", "Add Reagents", "Enter ID", "Choose ID")) + if("Enter ID") + var/valid_id + while(!valid_id) + chosen_reagent = stripped_input(usr, "Enter the ID of the reagent you want to add to your syringes.") + if(!chosen_reagent) //Get me out of here! + break + for(var/ID in reagent_ids) + if(ID == chosen_reagent) + valid_id = 1 + if(!valid_id) + to_chat(usr, "A reagent with that ID doesn't exist!") + if("Choose ID") + chosen_reagent = input(usr, "Choose a reagent to add to your syringes.", "Choose a reagent.") as null|anything in reagent_ids + if(chosen_reagent) + reagents.add_reagent(chosen_reagent, 100, null) + + else if (choose_operation == "Enable production") + if(!infinite) + infinite = TRUE + to_chat(user, "Now constantly generating reagents.") + else + infinite = FALSE + to_chat(user, "Reagents generation now off.") + + else + return \ No newline at end of file diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm index 3c599d51..b75131ed 100644 --- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -79,3 +79,10 @@ target.visible_message("\The [src] fails to land on target!") return TRUE + +//Chemlight was here, adding dumb bussing things + +/obj/item/projectile/bullet/dart/syringe/debug + name = "syringe" + icon_state = "syringeproj" + damage = 0 \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/Chemical_tongue.dm b/code/modules/reagents/reagent_containers/Chemical_tongue.dm new file mode 100644 index 00000000..2bed1f92 --- /dev/null +++ b/code/modules/reagents/reagent_containers/Chemical_tongue.dm @@ -0,0 +1,131 @@ +// This is more or less my funny tongue being being coded in. - Ken + +/obj/item/reagent_containers/chemical_tongue + name = "synthetic reagent tongue" + desc = "A cybernetic organ with the ability to produce reagents, neat!" + icon = 'icons/mob/dogborg.dmi' + icon_state = "synthtongue" + amount_per_transfer_from_this = 5 + volume = 200 + possible_transfer_amounts = list() + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + spillable = FALSE + splashable = FALSE + reagent_flags = OPENCONTAINER | NO_REACT + var/list/fun_ids = list("growthchem", "shrinkchem", "aphro", "aphro+", "penis_enlarger", "breast_enlarger", "space_drugs", "lithium") + +/obj/item/reagent_containers/chemical_tongue/attack(mob/M, mob/user, obj/target) + if(user.a_intent == INTENT_HARM && user.zone_selected == BODY_ZONE_PRECISE_MOUTH) + if(M != user) + M.visible_message("[user] locks their lips with [M], attempting to give a deep kiss to [M].", \ + "[user] locks their lips with yours, you feel what might be a tongue pushing past your lips then towards your throat!") + if(!do_mob(user, M, 80)) + return + playsound(M.loc,'sound/effects/attackblob.ogg', rand(10,50), 1) + if(isliving(M)) + var/mob/living/deepkiss = M + deepkiss.adjustOxyLoss(10) + if(!reagents || !reagents.total_volume) + M.visible_message("[user] pulls away from the kiss as their tongue in [M]'s mouth soon follows, slurping back into [user]'s muzzle.", \ + "[user] thrusts their tongue down your throat! Pulling it back up as it slithers up then out from your mouth.") + return // The drink might be empty after the delay, such as by spam-feeding + M.visible_message("[user] pulls away from the kiss as their tongue in [M]'s mouth soon follows, slurping back into [user]'s muzzle, leaving a long strand of liquid from their lips to [M]'s own before wiping it away.", \ + "[user] thrusts their tongue down your throat! Pulling it back up as it slithers up then out from your mouth. You feel a strange liquid in your throat!") + log_combat(user, M, "fed", reagents.log_list()) + var/fraction = min(5/reagents.total_volume, 1) + reagents.reaction(M, INGEST, fraction) + addtimer(CALLBACK(reagents, /datum/reagents.proc/copy_to, M, 10), 5) + + if(user.a_intent == INTENT_GRAB && user.zone_selected == BODY_ZONE_PRECISE_MOUTH) + if(M != user) + M.visible_message("[user] lightly places their lips on [M]'s providing a kiss.", \ + "[user] lightly places their lips against your, you can feel tongue pushing against your lips in the kiss.") + if(!do_mob(user, M, 40)) + return + playsound(M.loc,'sound/effects/attackblob.ogg', rand(10,50), 1) + if(!reagents || !reagents.total_volume) + M.visible_message("[user] breaks away from the kiss with [M]'s.", \ + "[user] rolls their tongue around the inside of your mouth, before pulling away.") + return // The drink might be empty after the delay, such as by spam-feeding + M.visible_message("[user] breaks away from the kiss with [M]'s.", \ + "[user] rolls their tongue around the inside of your mouth, before pulling away. You can almost taste something as [user]'s tongue was laced in something.") + log_combat(user, M, "fed", reagents.log_list()) + var/fraction = min(5/reagents.total_volume, 1) + reagents.reaction(M, INGEST, fraction) + addtimer(CALLBACK(reagents, /datum/reagents.proc/copy_to, M, 5), 5) + + if(user.a_intent == INTENT_DISARM && user.zone_selected == BODY_ZONE_PRECISE_MOUTH) + if(M != user) + M.visible_message("[user] attempts nuzzles into [M]'s.", \ + "[user] attempts to bump his snout against yours.") + if(!do_mob(user, M, 10)) + return + playsound(M.loc,'sound/effects/attackblob.ogg', rand(10,50), 1) + if(!reagents || !reagents.total_volume) + M.visible_message("[user] playfully licks over [M]'s lips.", \ + "[user] playfully licks over your lips.") + return // The drink might be empty after the delay, such as by spam-feeding + M.visible_message("[user] playfully licks over [M]'s lips.", \ + "[user] playfully licks over your lips, leaving some chemicals along it.") + log_combat(user, M, "fed", reagents.log_list()) + var/fraction = min(5/reagents.total_volume, 1) + reagents.reaction(M, INGEST, fraction) + addtimer(CALLBACK(reagents, /datum/reagents.proc/copy_to, M, 1), 5) + + if(user.a_intent == INTENT_HELP) + if(M != user && user.zone_selected == BODY_ZONE_PRECISE_MOUTH) + M.visible_message("[user] affectionately licks [M]'s lips.", \ + "[user] affectionately licks over your lips.") + playsound(M.loc,'sound/effects/attackblob.ogg', rand(10,50), 1) + + else + if(M != user) + M.visible_message("[user] affectionately licks [M].", \ + "[user] affectionately licks over you.") + playsound(M.loc,'sound/effects/attackblob.ogg', rand(10,50), 1) + else + return + +/obj/item/reagent_containers/chemical_tongue/attack_self(mob/user) + var/chosen_reagent + var/list/reagent_ids = sortList(GLOB.chemical_reagents_list) + var/quick_select = input(user, "Select an option", "Press start") in list("Quick Select", "Debug", "Cancel") + switch (quick_select) + if("Quick Select") + reagents.clear_reagents() + amount_per_transfer_from_this = 5 + chosen_reagent = input(user, "What reagent do you want to dispense?") as null|anything in fun_ids + if(chosen_reagent) + reagents.add_reagent(chosen_reagent, 20, null) + + if("Debug") + var/operation_selection = input(user, "Select an option", "Reagent fabricator", "cancel") in list("Select reagent", "Clear reagents", "Select transfer amount", "Cancel") + switch (operation_selection) + if("Select reagent") + switch(alert(usr, "Choose a method.", "Add Reagents", "Enter ID", "Choose ID")) + if("Enter ID") + var/valid_id + while(!valid_id) + chosen_reagent = stripped_input(usr, "Enter the ID of the reagent you want to add.") + if(!chosen_reagent) //Get me out of here! + break + for(var/ID in reagent_ids) + if(ID == chosen_reagent) + valid_id = 1 + if(!valid_id) + to_chat(usr, "A reagent with that ID doesn't exist!") + if("Choose ID") + chosen_reagent = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in reagent_ids + if(chosen_reagent) + reagents.add_reagent(chosen_reagent, 20, null) + + if("Clear reagents") + reagents.clear_reagents() + + if("Select transfer amount") + var/transfer_select = input(user, "Select the amount of reagents you'd like to transfer.", "Transfer amount") as num|null + if(transfer_select) + amount_per_transfer_from_this = max(min(round(text2num(transfer_select)),20),1) + + else + return \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 4381be1a..daee636c 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -181,3 +181,77 @@ volume = 250 list_reagents = list("holywater" = 150, "tiresolution" = 50, "dizzysolution" = 50) amount_per_transfer_from_this = 50 + +//Chemlight was here. + +/obj/item/reagent_containers/hypospray/debug + name = "retractable hypospray syringe" + desc = "An advanced chemical synthesizer and injection system, designed for heavy-duty medical equipment." + icon = 'icons/obj/syringe.dmi' + item_state = "hypo" + icon_state = "borghypo" + amount_per_transfer_from_this = 5 + volume = 200 + possible_transfer_amounts = list() + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + reagent_flags = OPENCONTAINER | NO_REACT + slot_flags = ITEM_SLOT_BELT + infinite = TRUE + var/list/fun_ids = list("growthchem", "shrinkchem", "aphro", "aphro+", "penis_enlarger", "breast_enlarger", "space_drugs", "lithium") + +/obj/item/reagent_containers/hypospray/debug/attack_self(mob/user) + var/chosen_reagent + var/list/reagent_ids = sortList(GLOB.chemical_reagents_list) + var/quick_select = input(user, "Select an option", "Press start") in list("Quick menu", "Debug", "Cancel") + switch (quick_select) + if("Quick menu") + var/list_selection = input(user, "Choose an catagory", "List Choice") in list("Emergency Meds", "Fun Chemicals", "Self Defense", "Cancel") + switch(list_selection) + if("Emergency Meds") + reagents.clear_reagents() + amount_per_transfer_from_this = 10 + reagents.add_reagent_list(list("atropine" = 10, "oxandrolone" = 20, "sal_acid" = 20, "salbutamol" = 10)) + + if("Self Defense") + reagents.clear_reagents() + amount_per_transfer_from_this = 10 + reagents.add_reagent_list(list("tirizene" = 14, "tiresolution" = 21, "bonehurtingjuice" = 14,)) // OOF + + if("Fun Chemicals") + reagents.clear_reagents() + amount_per_transfer_from_this = 5 + chosen_reagent = input(user, "What reagent do you want to dispense?") as null|anything in fun_ids + if(chosen_reagent) + reagents.add_reagent(chosen_reagent, 20, null) + + if("Debug") + var/operation_selection = input(user, "Select an option", "Reagent fabricator", "cancel") in list("Select reagent", "Clear reagents", "Select transfer amount", "Cancel") + switch (operation_selection) + if("Select reagent") + switch(alert(usr, "Choose a method.", "Add Reagents", "Enter ID", "Choose ID")) + if("Enter ID") + var/valid_id + while(!valid_id) + chosen_reagent = stripped_input(usr, "Enter the ID of the reagent you want to add.") + if(!chosen_reagent) //Get me out of here! + break + for(var/ID in reagent_ids) + if(ID == chosen_reagent) + valid_id = 1 + if(!valid_id) + to_chat(usr, "A reagent with that ID doesn't exist!") + if("Choose ID") + chosen_reagent = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in reagent_ids + if(chosen_reagent) + reagents.add_reagent(chosen_reagent, 20, null) + + if("Clear reagents") + reagents.clear_reagents() + + if("Select transfer amount") + var/transfer_select = input(user, "Select the amount of reagents you'd like to inject.", "Transfer amount") as num|null + if(transfer_select) + amount_per_transfer_from_this = max(min(round(text2num(transfer_select)),20),1) + + else + return \ No newline at end of file diff --git a/code/modules/spells/spell_types/adminbussed.dm b/code/modules/spells/spell_types/adminbussed.dm new file mode 100644 index 00000000..ca9e05e0 --- /dev/null +++ b/code/modules/spells/spell_types/adminbussed.dm @@ -0,0 +1,171 @@ +// Testing things +/obj/effect/proc_holder/spell/self/Alteration_Mechanical + name = "Alter figure" + desc = "Change and alter your physical form." + human_req = 1 + clothes_req = 0 + charge_max = 100 + cooldown_min = 50 + action_icon = 'icons/mob/actions/actions_changeling.dmi' + action_icon_state = "ling_transform" + action_background_icon_state = "bg_spell" + still_recharging_msg = "Your reagents are still recharging." + invocation = null //what is uttered when the wizard casts the spell + invocation_emote_self = null + school = null + sound = 'sound/effects/pop.ogg' + var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread + var/pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/rped.ogg' + +/obj/effect/proc_holder/spell/self/Alteration_Mechanical/cast(mob/living/carbon/human/user) + var/mob/living/carbon/human/H = user + var/list/reagent_options = sortList(GLOB.chemical_reagents_list) + H.visible_message(" user] gains a look of \ + concentration while standing perfectly still.\ + Their body seems to shift and starts reshaping itself.", + "You focus intently on altering your body while \ + standing perfectly still...") + var/select_alteration = input(user, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Genitals", "Penis", "Vagina", "Penis Length", "Breast Size", "Penis Production", "Breast Production", "Alter Height", "Cancel") + do_sparks(5, FALSE, user.loc) + if (select_alteration == "Genitals") + var/list/organs = list() + var/operation = input("Select organ operation.", "Organ Manipulation", "cancel") in list("add sexual organ", "remove sexual organ", "cancel") + switch(operation) + if("add sexual organ") + var/new_organ = input("Select sexual organ:", "Organ Manipulation") in list("Penis", "Testicles", "Breasts", "Vagina", "Womb", "Cancel") + if(new_organ == "Penis") + H.give_penis() + else if(new_organ == "Testicles") + H.give_balls() + else if(new_organ == "Breasts") + H.give_breasts() + else if(new_organ == "Vagina") + H.give_vagina() + else if(new_organ == "Womb") + H.give_womb() + else + return + if("remove sexual organ") + for(var/obj/item/organ/genital/X in H.internal_organs) + var/obj/item/organ/I = X + organs["[I.name] ([I.type])"] = I + var/obj/item/organ = input("Select sexual organ:", "Organ Manipulation", null) in organs + organ = organs[organ] + if(!organ) + return + var/obj/item/organ/genital/O + if(isorgan(organ)) + O = organ + O.Remove(H) + organ.forceMove(get_turf(H)) + qdel(organ) + H.update_genitals() + + else if (select_alteration == "Penis") + for(var/obj/item/organ/genital/penis/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(user, "Choose your character's dong", "Genital Alteration") as null|anything in GLOB.cock_shapes_list + if(new_shape) + H.dna.features["cock_shape"] = new_shape + H.update_genitals() + H.give_balls() + H.give_penis() + H.apply_overlay() + + else if (select_alteration == "Vagina") + for(var/obj/item/organ/genital/vagina/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(user, "Choose your character's pussy", "Genital Alteration") as null|anything in GLOB.vagina_shapes_list + if(new_shape) + H.dna.features["vag_shape"] = new_shape + H.update_genitals() + H.give_womb() + H.give_vagina() + H.apply_overlay() + + else if (select_alteration == "Penis Length") + for(var/obj/item/organ/genital/penis/X in H.internal_organs) + qdel(X) + var/new_length + new_length = input(user, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Genital Alteration") as num|null + if(new_length) + H.dna.features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN) + H.update_genitals() + H.apply_overlay() + H.give_balls() + H.give_penis() + + else if (select_alteration == "Breast Size") + for(var/obj/item/organ/genital/breasts/X in H.internal_organs) + qdel(X) + var/new_size + new_size = input(user, "Breast Size", "Genital Alteration") as null|anything in GLOB.breasts_size_list + if(new_size) + H.dna.features["breasts_size"] = new_size + H.update_genitals() + H.apply_overlay() + H.give_breasts() + + else if (select_alteration == "Penis Production") + if(H.getorganslot("testicles")) + var/obj/item/organ/genital/testicles/T = H.getorganslot("testicles") + var/new_fluid_penis + switch(alert(usr, "Choose a method.", "Add Reagents", "Enter ID", "Choose ID")) + if("Enter ID") + var/valid_id + while(!valid_id) + new_fluid_penis = stripped_input(usr, "Enter the ID of the reagent you want to add to your testicles.") + if(!new_fluid_penis) //Get me out of here! + break + for(var/ID in reagent_options) + if(ID == new_fluid_penis) + valid_id = 1 + if(!valid_id) + to_chat(usr, "A reagent with that ID doesn't exist!") + if("Choose ID") + new_fluid_penis = input(usr, "Choose a reagent to add to your testicles.", "Choose a reagent.") as null|anything in reagent_options + if(new_fluid_penis) + T.fluid_id = new_fluid_penis + H.update_genitals() + H.apply_overlay() + else + to_chat(user, "You need balls for this to work.") + + else if(select_alteration == "Breast Production") + if(H.getorganslot("breasts")) + var/obj/item/organ/genital/testicles/B = H.getorganslot("breasts") + var/new_fluid_breasts + switch(alert(usr, "Choose a method.", "Add Reagents", "Enter ID", "Choose ID")) + if("Enter ID") + var/valid_id + while(!valid_id) + new_fluid_breasts = stripped_input(usr, "Enter the ID of the reagent you want to add to your breasts.") + if(!new_fluid_breasts) //Get me out of here! + break + for(var/ID in reagent_options) + if(ID == new_fluid_breasts) + valid_id = 1 + if(!valid_id) + to_chat(usr, "A reagent with that ID doesn't exist!") + if("Choose ID") + new_fluid_breasts = input(usr, "Choose a reagent to add to your breasts.", "Choose a reagent.") as null|anything in reagent_options + if(new_fluid_breasts) + B.fluid_id = new_fluid_breasts + H.update_genitals() + H.apply_overlay() + else + to_chat(user, "You need functioning breasts for this to work.") + + else if (select_alteration == "Alter Height") + var/altered_height + altered_height = input(user, "Choose your desired sprite size:\n([MIN_BODYSIZE]-400%)", "Height Alteration") as num|null + if(altered_height) + H.size_multiplier = (max(min( round(text2num(altered_height)),400),MIN_BODYSIZE))/100 + playsound(user.loc, pshoom_or_beepboopblorpzingshadashwoosh, 40, 1) + do_sparks(5, FALSE, user.loc) + H.visible_message("[pick("[H] shifts in size!", "[H] alters in height!", "[H] reshapes into a new stature!")]") + + else + return \ No newline at end of file diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index 09ba9ca7..700a62dd 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -234,3 +234,10 @@ name = "surgical toolset implant" desc = "A set of surgical tools hidden behind a concealed panel on the user's arm." contents = newlist(/obj/item/retractor/augment, /obj/item/hemostat/augment, /obj/item/cautery/augment, /obj/item/surgicaldrill/augment, /obj/item/scalpel/augment, /obj/item/circular_saw/augment, /obj/item/surgical_drapes) + +//Ignore this one this is for a bus character. + +/obj/item/organ/cyberimp/arm/COMPound + name = "chemical cybernetics implant" + desc = "A powerful cybernetic implant that contains chemical fabrication modules built into the user's arm." + contents = newlist(/obj/item/reagent_containers/hypospray/debug, /obj/item/gun/chem/debug, /obj/item/reagent_containers/chemical_tongue, /obj/item/fermichem/pHmeter) \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 9a5d6c13..3f1bee4f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1775,7 +1775,6 @@ #include "code\modules\holiday\easter.dm" #include "code\modules\holiday\holidays.dm" #include "code\modules\holiday\halloween\bartholomew.dm" -//#include "code\modules\holiday\halloween\halloween.dm" //Time to go ahead and disable this. See you next year. #include "code\modules\holiday\halloween\jacqueen.dm" #include "code\modules\holodeck\area_copy.dm" #include "code\modules\holodeck\computer.dm" @@ -2614,6 +2613,7 @@ #include "code\modules\reagents\reagent_containers\borghydro.dm" #include "code\modules\reagents\reagent_containers\bottle.dm" #include "code\modules\reagents\reagent_containers\chem_pack.dm" +#include "code\modules\reagents\reagent_containers\Chemical_tongue.dm" #include "code\modules\reagents\reagent_containers\dropper.dm" #include "code\modules\reagents\reagent_containers\glass.dm" #include "code\modules\reagents\reagent_containers\hypospray.dm" @@ -2788,6 +2788,7 @@ #include "code\modules\shuttle\syndicate.dm" #include "code\modules\shuttle\white_ship.dm" #include "code\modules\spells\spell.dm" +#include "code\modules\spells\spell_types\adminbussed.dm" #include "code\modules\spells\spell_types\aimed.dm" #include "code\modules\spells\spell_types\area_teleport.dm" #include "code\modules\spells\spell_types\barnyard.dm"