diff --git a/.travis.yml b/.travis.yml index f03baeb71f..3751bb249f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ sudo: false env: BYOND_MAJOR="509" BYOND_MINOR="1318" - MACRO_COUNT=1004 + MACRO_COUNT=996 cache: directories: diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 3441f5ce2a..4a84b66083 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -38,24 +38,37 @@ #define LIFE_HUD 10 // STATUS_HUD that only reports dead or alive //some colors -#define COLOR_WHITE "#FFFFFF" -#define COLOR_SILVER "#C0C0C0" -#define COLOR_GRAY "#808080" -#define COLOR_BLACK "#000000" -#define COLOR_RED "#FF0000" -#define COLOR_MAROON "#800000" -#define COLOR_YELLOW "#FFFF00" -#define COLOR_OLIVE "#808000" -#define COLOR_LIME "#00FF00" -#define COLOR_GREEN "#008000" -#define COLOR_CYAN "#00FFFF" -#define COLOR_TEAL "#008080" -#define COLOR_BLUE "#0000FF" -#define COLOR_NAVY "#000080" -#define COLOR_PINK "#FF00FF" -#define COLOR_PURPLE "#800080" -#define COLOR_ORANGE "#FF9900" -#define COLOR_LUMINOL "#66FFFF" +#define COLOR_WHITE "#FFFFFF" +#define COLOR_SILVER "#C0C0C0" +#define COLOR_GRAY "#808080" +#define COLOR_BLACK "#000000" +#define COLOR_RED "#FF0000" +#define COLOR_MAROON "#800000" +#define COLOR_YELLOW "#FFFF00" +#define COLOR_OLIVE "#808000" +#define COLOR_LIME "#00FF00" +#define COLOR_GREEN "#008000" +#define COLOR_CYAN "#00FFFF" +#define COLOR_TEAL "#008080" +#define COLOR_BLUE "#0000FF" +#define COLOR_NAVY "#000080" +#define COLOR_PINK "#FF00FF" +#define COLOR_PURPLE "#800080" +#define COLOR_ORANGE "#FF9900" +#define COLOR_LUMINOL "#66FFFF" +#define COLOR_BEIGE "#CEB689" +#define COLOR_BLUE_GRAY "#6A97B0" +#define COLOR_BROWN "#B19664" +#define COLOR_DARK_BROWN "#917448" +#define COLOR_DARK_ORANGE "#B95A00" +#define COLOR_GREEN_GRAY "#8DAF6A" +#define COLOR_RED_GRAY "#AA5F61" +#define COLOR_PALE_BLUE_GRAY "#8BBBD5" +#define COLOR_PALE_GREEN_GRAY "#AED18B" +#define COLOR_PALE_RED_GRAY "#CC9090" +#define COLOR_PALE_PURPLE_GRAY "#BDA2BA" +#define COLOR_PURPLE_GRAY "#A2819E" + // Shuttles. // These define the time taken for the shuttle to get to the space station, and the time before it leaves again. @@ -143,19 +156,6 @@ #define PROJECTILE_CONTINUE -1 //if the projectile should continue flying after calling bullet_act() #define PROJECTILE_FORCE_MISS -2 //if the projectile should treat the attack as a miss (suppresses attack and admin logs) - only applies to mobs. -// Custom colors -#define COLOR_BEIGE "#CEB689" -#define COLOR_BLUE_GRAY "#6A97B0" -#define COLOR_BROWN "#B19664" -#define COLOR_DARK_BROWN "#917448" -#define COLOR_DARK_ORANGE "#B95A00" -#define COLOR_GREEN_GRAY "#8DAF6A" -#define COLOR_RED_GRAY "#AA5F61" -#define COLOR_PALE_BLUE_GRAY "#8BBBD5" -#define COLOR_PALE_GREEN_GRAY "#AED18B" -#define COLOR_PALE_RED_GRAY "#CC9090" -#define COLOR_PALE_PURPLE_GRAY "#BDA2BA" -#define COLOR_PURPLE_GRAY "#A2819E" // Vending stuff #define CAT_NORMAL 1 diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 8bac7f560c..df633d1ae5 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -13,7 +13,6 @@ #define GODMODE 0x1000 #define FAKEDEATH 0x2000 // Replaces stuff like changeling.changeling_fakedeath. #define DISFIGURED 0x4000 // Set but never checked. Remove this sometime and replace occurences with the appropriate organ code -#define XENO_HOST 0x8000 // Tracks whether we're gonna be a baby alien's mummy. // Grab levels. #define GRAB_PASSIVE 1 diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index 06b277257f..d5a7b1ed46 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -248,6 +248,34 @@ . |= M // Since we're already looping through mobs, why bother using |= ? This only slows things down. return . +/proc/get_mobs_and_objs_in_view_fast(var/turf/T, var/range) + var/list/results = list("objs" = list(), "mobs" = list()) + + var/list/hear = dview(range,T,INVISIBILITY_MAXIMUM) + var/list/hearturfs = list() + + for(var/I in hear) + if(ismob(I)) + var/mob/M = I + results["mobs"] += M + hearturfs += M.locs[1] + else if(isobj(I)) + var/obj/O = I + results["objs"] += I + hearturfs += O.locs[1] + + + for(var/mob/M in player_list) + if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) + results["mobs"] |= M + continue + if(M.loc && M.locs[1] in hearturfs) + results["mobs"] |= M + + return results + + + #define SIGN(X) ((X<0)?-1:1) proc diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index b770693a69..0858ebc1a4 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -1039,10 +1039,9 @@ proc/get_mob_with_client_list() //gets the turf the atom is located in (or itself, if it is a turf). //returns null if the atom is not in a turf. -/proc/get_turf(atom/A) - if(!istype(A)) return - for(A, A && !isturf(A), A=A.loc); - return A +/proc/get_turf(atom/movable/A) + if(isturf(A)) return A + if(A && A.locs.len) return A.locs[1] /proc/get(atom/loc, type) while(loc) diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index a50680ef8d..a4553403bc 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -148,9 +148,9 @@ if(reas) reason = reas if ("duration") - var/dur = input("Duration (in minutes) during which pass is valid (up to 30 minutes).", "Duration") as num|null + var/dur = input("Duration (in minutes) during which pass is valid (up to 120 minutes).", "Duration") as num|null if (dur) - if (dur > 0 && dur <= 30) + if (dur > 0 && dur <= 120) duration = dur else usr << "Invalid duration." @@ -158,7 +158,7 @@ var/A = text2num(href_list["access"]) if (A in accesses) accesses.Remove(A) - else + else if(A in giver.access) //Let's make sure the ID card actually has the access. accesses.Add(A) else diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 912bacb817..f086a3e1dd 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -907,7 +907,7 @@ /obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3, /obj/item/seeds/poppyseed = 3,/obj/item/seeds/sugarcaneseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/peanutseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3, /obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,/obj/item/seeds/plumpmycelium = 2, - /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3) + /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3,/obj/item/seeds/lavenderseed = 3) contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/mtearseed = 2, /obj/item/seeds/nettleseed = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/shandseed = 2,) premium = list(/obj/item/toy/waterflower = 1) @@ -1047,3 +1047,24 @@ /obj/item/weapon/screwdriver = 5,/obj/item/weapon/crowbar = 5) //everything after the power cell had no amounts, I improvised. -Sayu +/obj/machinery/vending/fitness + name = "SweatMAX" + desc = "Fueled by your inner inadequacy!" + icon_state = "fitness" + products = list(/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton = 8, + /obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate = 8, + /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/proteinshake = 8, + /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask = 8, + /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 8, + /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 8, + /obj/item/weapon/reagent_containers/pill/diet = 8) + + prices = list(/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton = 3, + /obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate = 3, + /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/proteinshake = 20, + /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask = 5, + /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 5, + /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 5, + /obj/item/weapon/reagent_containers/pill/diet = 25) + + contraband = list(/obj/item/weapon/reagent_containers/syringe/steroid = 4) diff --git a/code/game/mecha/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm index ede4ccf410..65ed711f2f 100644 --- a/code/game/mecha/medical/odysseus.dm +++ b/code/game/mecha/medical/odysseus.dm @@ -101,8 +101,6 @@ holder = patient.hud_list[STATUS_HUD] if(patient.stat == 2) holder.icon_state = "huddead" - else if(patient.status_flags & XENO_HOST) - holder.icon_state = "hudxeno" else if(foundVirus) holder.icon_state = "hudill" else if(patient.has_brain_worms()) diff --git a/code/game/objects/effects/decals/posters/bs12.dm b/code/game/objects/effects/decals/posters/bs12.dm index a727e2804c..091b8cb2c9 100644 --- a/code/game/objects/effects/decals/posters/bs12.dm +++ b/code/game/objects/effects/decals/posters/bs12.dm @@ -91,7 +91,7 @@ /datum/poster/bay_19 icon_state="bsposter19" - name = "Respect a Unathi" + name = "Respect an Unathi" desc = "This poster depicts a well dressed looking Unathi receiving a prestigious award. It appears to espouse greater co-operation and harmony between the two races." /datum/poster/bay_20 diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index 34181486e4..1d171d9dbe 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -9,11 +9,15 @@ /obj/item/trash/raisins name = "\improper 4no raisins" - icon_state= "4no_raisins" + icon_state = "4no_raisins" /obj/item/trash/candy name = "candy" - icon_state= "candy" + icon_state = "candy" + +/obj/item/trash/candy/proteinbar + name = "protein bar" + icon_state = "proteinbar" /obj/item/trash/cheesie name = "\improper Cheesie Honkers" diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm index 0ccb1f1a24..7c8752c6d7 100644 --- a/code/game/objects/items/weapons/clown_items.dm +++ b/code/game/objects/items/weapons/clown_items.dm @@ -34,6 +34,10 @@ //So this is a workaround. This also makes more sense from an IC standpoint. ~Carn if(user.client && (target in user.client.screen)) user << "You need to take that [target.name] off before cleaning it." + else if(istype(target,/obj/effect/decal/cleanable/blood)) + user << "You scrub \the [target.name] out." + target.clean_blood() + return //Blood is a cleanable decal, therefore needs to be accounted for before all cleanable decals. else if(istype(target,/obj/effect/decal/cleanable)) user << "You scrub \the [target.name] out." qdel(target) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 478272b8b2..c0469cd9f8 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -187,7 +187,8 @@ /obj/item/device/flash, /obj/item/weapon/flame/lighter, /obj/item/weapon/reagent_containers/food/snacks/donut/, - /obj/item/ammo_magazine + /obj/item/ammo_magazine, + /obj/item/weapon/gun/projectile/colt/detective ) /obj/item/weapon/storage/belt/soulstone diff --git a/code/game/objects/items/weapons/towels.dm b/code/game/objects/items/weapons/towels.dm new file mode 100644 index 0000000000..180ccf2af9 --- /dev/null +++ b/code/game/objects/items/weapons/towels.dm @@ -0,0 +1,14 @@ +/obj/item/weapon/towel + name = "towel" + icon = 'icons/obj/weapons.dmi' + icon_state = "towel" + slot_flags = SLOT_HEAD | SLOT_BELT | SLOT_OCLOTHING + force = 3.0 + w_class = 3.0 + attack_verb = list("whipped") + hitsound = "towelwhip" + desc = "A soft cotton towel." + +/obj/item/weapon/towel/attack_self(mob/living/user as mob) + user.visible_message(text("[] uses [] to towel themselves off.", user, src)) + playsound(user, 'sound/weapons/towelwipe.ogg', 25, 1) diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index bc143fc60d..3e6ed27302 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -29,8 +29,6 @@ if(prefs.muted & MUTE_OOC) src << "You cannot use OOC (muted)." return - if(handle_spam_prevention(msg,MUTE_OOC)) - return if(findtext(msg, "byond://")) src << "Advertising other servers is not allowed." log_admin("[key_name(src)] has attempted to advertise in OOC: [msg]") @@ -99,8 +97,6 @@ if(prefs.muted & MUTE_OOC) src << "You cannot use OOC (muted)." return - if(handle_spam_prevention(msg, MUTE_OOC)) - return if(findtext(msg, "byond://")) src << "Advertising other servers is not allowed." log_admin("[key_name(src)] has attempted to advertise in OOC: [msg]") diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 23c5961b66..c7dc8f4ae1 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -910,7 +910,7 @@ proc/admin_notice(var/message, var/rights) for(var/datum/antagonist/antag in ticker.mode.antag_templates) if(antag.is_antagonist(M)) return 2 - else if(M.special_role) + if(M.special_role) return 1 if(isrobot(character)) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 504a8419bf..8f8532590e 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -17,9 +17,6 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," adminhelped = 1 //Determines if they get the message to reply by clicking the name. - if(src.handle_spam_prevention(msg,MUTE_ADMINHELP)) - return - //clean the input msg if(!msg) return diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 898cc4e835..bcb87f06d8 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -56,9 +56,6 @@ else src << "Error: Private-Message: Client not found. They may have lost connection, so try using an adminhelp!" return - if (src.handle_spam_prevention(msg,MUTE_ADMINHELP)) - return - //clean the message if it's not sent by a high-rank admin //todo: sanitize for all??? if(!check_rights(R_SERVER|R_DEBUG,0)) diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm index 11193a3f09..08eda6bb34 100644 --- a/code/modules/admin/verbs/deadsay.dm +++ b/code/modules/admin/verbs/deadsay.dm @@ -15,9 +15,6 @@ src << "You have deadchat muted." return - if (src.handle_spam_prevention(msg,MUTE_DEADCHAT)) - return - var/stafftype = uppertext(holder.rank) msg = sanitize(msg) diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 600549cdfa..23f5a75e2c 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -13,8 +13,6 @@ if(usr.client.prefs.muted & MUTE_PRAY) usr << "\red You cannot pray (muted)." return - if(src.client.handle_spam_prevention(msg,MUTE_PRAY)) - return var/image/cross = image('icons/obj/storage.dmi',"bible") msg = "\blue \icon[cross] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src, src)]) (CA) (SC): [msg]" diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 98c7cef326..b33b5746a9 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -74,21 +74,6 @@ ..() //redirect to hsrc.Topic() -/client/proc/handle_spam_prevention(var/message, var/mute_type) - if(config.automute_on && !holder && src.last_message == message) - src.last_message_count++ - if(src.last_message_count >= SPAM_TRIGGER_AUTOMUTE) - src << "\red You have exceeded the spam filter limit for identical messages. An auto-mute was applied." - cmd_admin_mute(src.mob, mute_type, 1) - return 1 - if(src.last_message_count >= SPAM_TRIGGER_WARNING) - src << "\red You are nearing the spam filter limit for identical messages." - return 0 - else - last_message = message - src.last_message_count = 0 - return 0 - //This stops files larger than UPLOAD_LIMIT being sent from client to server via input(), client.Import() etc. /client/AllowUpload(filename, filelength) if(filelength > UPLOAD_LIMIT) diff --git a/code/modules/client/preference_setup/loadout/loadout_general.dm b/code/modules/client/preference_setup/loadout/loadout_general.dm index 2b1c4bbb6b..c68037704e 100644 --- a/code/modules/client/preference_setup/loadout/loadout_general.dm +++ b/code/modules/client/preference_setup/loadout/loadout_general.dm @@ -61,3 +61,11 @@ lunchboxes[initial(lunchbox.name)] = lunchbox_type gear_tweaks += new/datum/gear_tweak/path(sortAssoc(lunchboxes)) gear_tweaks += new/datum/gear_tweak/contents(lunchables_lunches(), lunchables_snacks(), lunchables_drinks()) + +/datum/gear/towel + display_name = "towel" + path = /obj/item/weapon/towel + +/datum/gear/towel/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm index 5e368bfb81..a6665d0bb5 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm @@ -88,72 +88,72 @@ shorts[initial(short_type.name)] = short_type gear_tweaks += new/datum/gear_tweak/path(sortAssoc(shorts)) -/datum/gear/uniform/skirt/ce +/datum/gear/uniform/job_skirt/ce display_name = "skirt, ce" path = /obj/item/clothing/under/rank/engineer/chief_engineer/skirt allowed_roles = list("Chief Engineer") -/datum/gear/uniform/skirt/atmos +/datum/gear/uniform/job_skirt/atmos display_name = "skirt, atmos" path = /obj/item/clothing/under/rank/engineer/atmospheric_technician/skirt allowed_roles = list("Chief Engineer","Atmospheric Technician") -/datum/gear/uniform/skirt/eng +/datum/gear/uniform/job_skirt/eng display_name = "skirt, engineer" path = /obj/item/clothing/under/rank/engineer/skirt allowed_roles = list("Chief Engineer","Station Engineer") -/datum/gear/uniform/skirt/roboticist +/datum/gear/uniform/job_skirt/roboticist display_name = "skirt, roboticist" path = /obj/item/clothing/under/rank/roboticist/skirt allowed_roles = list("Research Director","Roboticist") -/datum/gear/uniform/skirt/cmo +/datum/gear/uniform/job_skirt/cmo display_name = "skirt, cmo" path = /obj/item/clothing/under/rank/medical/chief_medical_officer/skirt allowed_roles = list("Chief Medical Officer") -/datum/gear/uniform/skirt/chem +/datum/gear/uniform/job_skirt/chem display_name = "skirt, chemist" path = /obj/item/clothing/under/rank/medical/chemist/skirt allowed_roles = list("Chief Medical Officer","Chemist") -/datum/gear/uniform/skirt/viro +/datum/gear/uniform/job_skirt/viro display_name = "skirt, virologist" path = /obj/item/clothing/under/rank/medical/virologist/skirt allowed_roles = list("Chief Medical Officer","Medical Doctor") -/datum/gear/uniform/skirt/med +/datum/gear/uniform/job_skirt/med display_name = "skirt, medical" path = /obj/item/clothing/under/rank/medical/skirt allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Psychiatrist","Paramedic") -/datum/gear/uniform/skirt/sci +/datum/gear/uniform/job_skirt/sci display_name = "skirt, scientist" path = /obj/item/clothing/under/rank/scientist/skirt allowed_roles = list("Research Director","Scientist", "Xenobiologist") -/datum/gear/uniform/skirt/cargo +/datum/gear/uniform/job_skirt/cargo display_name = "skirt, cargo" path = /obj/item/clothing/under/rank/cargotech/skirt allowed_roles = list("Quartermaster","Cargo Technician") -/datum/gear/uniform/skirt/qm +/datum/gear/uniform/job_skirt/qm display_name = "skirt, QM" path = /obj/item/clothing/under/rank/cargo/skirt allowed_roles = list("Quartermaster") -/datum/gear/uniform/skirt/warden +/datum/gear/uniform/job_skirt/warden display_name = "skirt, warden" path = /obj/item/clothing/under/rank/security/warden/skirt allowed_roles = list("Head of Security", "Warden") -/datum/gear/uniform/skirt/security +/datum/gear/uniform/job_skirt/security display_name = "skirt, security" path = /obj/item/clothing/under/rank/security/skirt allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer") -/datum/gear/uniform/skirt/head_of_security +/datum/gear/uniform/job_skirt/head_of_security display_name = "skirt, hos" path = /obj/item/clothing/under/rank/security/head_of_security/skirt allowed_roles = list("Head of Security") diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 8c6fd55c69..dd16651136 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -678,27 +678,16 @@ if (src.loc == usr) switch(sensor_mode) if(0) - usr << "You disable your suit's remote sensing equipment." + usr.visible_message("[usr] adjusts their sensors.", "You disable your suit's remote sensing equipment.") if(1) - usr << "Your suit will now report whether you are live or dead." + usr.visible_message("[usr] adjusts their sensors.", "Your suit will now report whether you are live or dead.") if(2) - usr << "Your suit will now report your vital lifesigns." + usr.visible_message("[usr] adjusts their sensors.", "Your suit will now report your vital lifesigns.") if(3) - usr << "Your suit will now report your vital lifesigns as well as your coordinate position." + usr.visible_message("[usr] adjusts their sensors.", "Your suit will now report your vital lifesigns as well as your coordinate position.") + else if (istype(src.loc, /mob)) - switch(sensor_mode) - if(0) - for(var/mob/V in viewers(usr, 1)) - V.show_message("\red [usr] disables [src.loc]'s remote sensing equipment.", 1) - if(1) - for(var/mob/V in viewers(usr, 1)) - V.show_message("[usr] turns [src.loc]'s remote sensors to binary.", 1) - if(2) - for(var/mob/V in viewers(usr, 1)) - V.show_message("[usr] sets [src.loc]'s sensors to track vitals.", 1) - if(3) - for(var/mob/V in viewers(usr, 1)) - V.show_message("[usr] sets [src.loc]'s sensors to maximum.", 1) + usr.visible_message("[usr] adjusts [src.loc]'s sensors.", "You adjust [src.loc]'s sensors.") /obj/item/clothing/under/verb/toggle() set name = "Toggle Suit Sensors" diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 26d7de9082..4d90082708 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -133,7 +133,6 @@ chest = new chest_type(src) if(allowed) chest.allowed = allowed - chest.slowdown = offline_slowdown verbs |= /obj/item/weapon/rig/proc/toggle_chest for(var/obj/item/piece in list(gloves,helmet,boots,chest)) @@ -332,14 +331,14 @@ offline = 0 if(istype(wearer) && !wearer.wearing_rig) wearer.wearing_rig = src - chest.slowdown = initial(slowdown) + slowdown = initial(slowdown) if(offline) if(offline == 1) for(var/obj/item/rig_module/module in installed_modules) module.deactivate() offline = 2 - chest.slowdown = offline_slowdown + slowdown = offline_slowdown return if(cell && cell.charge > 0 && electrified > 0) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index bfcde568e9..b856f8a8bb 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -46,14 +46,14 @@ desc = "An armoured jacket with silver rank pips and livery." icon_state = "warden_jacket" item_state = "armor" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS /obj/item/clothing/suit/armor/vest/warden/alt name = "Warden's jacket" desc = "An armoured jacket with silver rank pips and livery." icon_state = "warden_alt" item_state = "warden_alt" - body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS /obj/item/clothing/suit/armor/riot diff --git a/code/modules/clothing/under/shorts.dm b/code/modules/clothing/under/shorts.dm index c4b712c4c3..b04621bdfe 100644 --- a/code/modules/clothing/under/shorts.dm +++ b/code/modules/clothing/under/shorts.dm @@ -116,26 +116,31 @@ name = "khaki skirt" desc = "A skirt that is a khaki color." icon_state = "skirt_khaki" + worn_state = "skirt_khaki" /obj/item/clothing/under/skirt/black name = "short black skirt" desc = "A skirt that is a shiny black." icon_state = "skirt_short_black" + worn_state = "skirt_short_black" /obj/item/clothing/under/skirt/blue name = "short blue skirt" desc = "A skirt that is a shiny blue." icon_state = "skirt_short_blue" + worn_state = "skirt_short_blue" /obj/item/clothing/under/skirt/red name = "short red skirt" desc = "A skirt that is a shiny red." icon_state = "skirt_short_red" + worn_state = "skirt_short_red" /obj/item/clothing/under/skirt/swept name = "swept skirt" desc = "A skirt that is swept to one side." icon_state = "skirt_swept" + worn_state = "skirt_swept" /obj/item/clothing/under/skirt/plaid_blue name = "blue plaid skirt" diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index 6887ef1fba..b279ab63d5 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -49,7 +49,7 @@ if(!on_fire && istype(W, /obj/item/weapon/flame)) var/obj/item/weapon/flame/F = W if(F.lit) - ignite() + src.ignite() if(on_fire) visible_message("\The [user] lights [src] with [W].") else @@ -151,7 +151,7 @@ /obj/item/weapon/reagent_containers/glass/rag/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature >= 50 + T0C) - ignite() + src.ignite() if(exposed_temperature >= 900 + T0C) new /obj/effect/decal/cleanable/ash(get_turf(src)) qdel(src) diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm index 69032cd5ce..6ac9483e2f 100644 --- a/code/modules/flufftext/Dreaming.dm +++ b/code/modules/flufftext/Dreaming.dm @@ -11,7 +11,7 @@ var/list/dreams = list( "the quartermaster","a cargo technician","the botanist","a shaft miner","the psychologist","the chemist","the geneticist", "the virologist","the roboticist","the chef","the bartender","the chaplain","the librarian","a mouse","an ert member", "a beach","the holodeck","a smokey room","a voice","the cold","a mouse","an operating table","the bar","the rain","a skrell", - "a unathi","a tajaran","the ai core","the mining station","the research station","a beaker of strange liquid", + "an unathi","a tajaran","the ai core","the mining station","the research station","a beaker of strange liquid", ) mob/living/carbon/proc/dream() diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index 157d4acbd3..6e88aabee5 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -550,6 +550,25 @@ set_trait(TRAIT_WATER_CONSUMPTION, 6) set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15) +/datum/seed/flower/lavender + name = "lavender" + seed_name = "lavender" + display_name = "lavender" + chems = list("nutriment" = list(1,20), "bicaridine" = list(1,10)) + +/datum/seed/flower/lavender/New() + ..() + set_trait(TRAIT_MATURATION,7) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,5) + set_trait(TRAIT_PRODUCT_ICON,"flower6") + set_trait(TRAIT_PRODUCT_COLOUR,"#B57EDC") + set_trait(TRAIT_PLANT_COLOUR,"#6B8C5E") + set_trait(TRAIT_PLANT_ICON,"flower4") + set_trait(TRAIT_IDEAL_LIGHT, 7) + set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.05) + set_trait(TRAIT_WATER_CONSUMPTION, 0.5) + //Grapes/varieties /datum/seed/grapes name = "grapes" diff --git a/code/modules/hydroponics/seed_packets.dm b/code/modules/hydroponics/seed_packets.dm index e14fbd792b..7c1b70c4c7 100644 --- a/code/modules/hydroponics/seed_packets.dm +++ b/code/modules/hydroponics/seed_packets.dm @@ -197,6 +197,9 @@ var/global/list/plant_seed_sprites = list() /obj/item/seeds/sunflowerseed seed_type = "sunflowers" +/obj/item/seeds/lavenderseed + seed_type = "lavender" + /obj/item/seeds/brownmold seed_type = "mold" diff --git a/code/modules/hydroponics/seed_storage.dm b/code/modules/hydroponics/seed_storage.dm index 448173104b..fe0a178919 100644 --- a/code/modules/hydroponics/seed_storage.dm +++ b/code/modules/hydroponics/seed_storage.dm @@ -40,12 +40,91 @@ /obj/machinery/seed_storage/garden name = "Garden seed storage" scanner = list("stats") - starting_seeds = list(/obj/item/seeds/appleseed = 3, /obj/item/seeds/bananaseed = 3, /obj/item/seeds/berryseed = 3, /obj/item/seeds/cabbageseed = 3, /obj/item/seeds/carrotseed = 3, /obj/item/seeds/chantermycelium = 3, /obj/item/seeds/cherryseed = 3, /obj/item/seeds/chiliseed = 3, /obj/item/seeds/cocoapodseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/grapeseed = 3, /obj/item/seeds/grassseed = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/lemonseed = 3, /obj/item/seeds/limeseed = 3, /obj/item/seeds/mtearseed = 2, /obj/item/seeds/orangeseed = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/plumpmycelium = 3, /obj/item/seeds/poppyseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/pumpkinseed = 3, /obj/item/seeds/riceseed = 3, /obj/item/seeds/soyaseed = 3, /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/shandseed = 2, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, /obj/item/seeds/watermelonseed = 3, /obj/item/seeds/wheatseed = 3, /obj/item/seeds/whitebeetseed = 3) + starting_seeds = list( + /obj/item/seeds/appleseed = 3, + /obj/item/seeds/bananaseed = 3, + /obj/item/seeds/berryseed = 3, + /obj/item/seeds/cabbageseed = 3, + /obj/item/seeds/carrotseed = 3, + /obj/item/seeds/chantermycelium = 3, + /obj/item/seeds/cherryseed = 3, + /obj/item/seeds/chiliseed = 3, + /obj/item/seeds/cocoapodseed = 3, + /obj/item/seeds/cornseed = 3, + /obj/item/seeds/eggplantseed = 3, + /obj/item/seeds/grapeseed = 3, + /obj/item/seeds/grassseed = 3, + /obj/item/seeds/replicapod = 3, + /obj/item/seeds/lemonseed = 3, + /obj/item/seeds/limeseed = 3, + /obj/item/seeds/mtearseed = 2, + /obj/item/seeds/orangeseed = 3, + /obj/item/seeds/peanutseed = 3, + /obj/item/seeds/plumpmycelium = 3, + /obj/item/seeds/poppyseed = 3, + /obj/item/seeds/potatoseed = 3, + /obj/item/seeds/pumpkinseed = 3, + /obj/item/seeds/riceseed = 3, + /obj/item/seeds/soyaseed = 3, + /obj/item/seeds/sugarcaneseed = 3, + /obj/item/seeds/sunflowerseed = 3, + /obj/item/seeds/shandseed = 2, + /obj/item/seeds/tobaccoseed = 3, + /obj/item/seeds/tomatoseed = 3, + /obj/item/seeds/towermycelium = 3, + /obj/item/seeds/watermelonseed = 3, + /obj/item/seeds/wheatseed = 3, + /obj/item/seeds/whitebeetseed = 3, + /obj/item/seeds/lavenderseed = 3 + ) /obj/machinery/seed_storage/xenobotany name = "Xenobotany seed storage" scanner = list("stats", "produce", "soil", "temperature", "light") - starting_seeds = list(/obj/item/seeds/ambrosiavulgarisseed = 3, /obj/item/seeds/appleseed = 3, /obj/item/seeds/amanitamycelium = 2, /obj/item/seeds/bananaseed = 3, /obj/item/seeds/berryseed = 3, /obj/item/seeds/cabbageseed = 3, /obj/item/seeds/carrotseed = 3, /obj/item/seeds/chantermycelium = 3, /obj/item/seeds/cherryseed = 3, /obj/item/seeds/chiliseed = 3, /obj/item/seeds/cocoapodseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/glowshroom = 2, /obj/item/seeds/grapeseed = 3, /obj/item/seeds/grassseed = 3, /obj/item/seeds/lemonseed = 3, /obj/item/seeds/libertymycelium = 2, /obj/item/seeds/limeseed = 3, /obj/item/seeds/mtearseed = 2, /obj/item/seeds/nettleseed = 2, /obj/item/seeds/orangeseed = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/plastiseed = 3, /obj/item/seeds/plumpmycelium = 3, /obj/item/seeds/poppyseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/pumpkinseed = 3, /obj/item/seeds/reishimycelium = 2, /obj/item/seeds/riceseed = 3, /obj/item/seeds/soyaseed = 3, /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/shandseed = 2, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, /obj/item/seeds/watermelonseed = 3, /obj/item/seeds/wheatseed = 3, /obj/item/seeds/whitebeetseed = 3) + starting_seeds = list( + /obj/item/seeds/ambrosiavulgarisseed = 3, + /obj/item/seeds/appleseed = 3, + /obj/item/seeds/amanitamycelium = 2, + /obj/item/seeds/bananaseed = 3, + /obj/item/seeds/berryseed = 3, + /obj/item/seeds/cabbageseed = 3, + /obj/item/seeds/carrotseed = 3, + /obj/item/seeds/chantermycelium = 3, + /obj/item/seeds/cherryseed = 3, + /obj/item/seeds/chiliseed = 3, + /obj/item/seeds/cocoapodseed = 3, + /obj/item/seeds/cornseed = 3, + /obj/item/seeds/replicapod = 3, + /obj/item/seeds/eggplantseed = 3, + /obj/item/seeds/glowshroom = 2, + /obj/item/seeds/grapeseed = 3, + /obj/item/seeds/grassseed = 3, + /obj/item/seeds/lemonseed = 3, + /obj/item/seeds/libertymycelium = 2, + /obj/item/seeds/limeseed = 3, + /obj/item/seeds/mtearseed = 2, + /obj/item/seeds/nettleseed = 2, + /obj/item/seeds/orangeseed = 3, + /obj/item/seeds/peanutseed = 3, + /obj/item/seeds/plastiseed = 3, + /obj/item/seeds/plumpmycelium = 3, + /obj/item/seeds/poppyseed = 3, + /obj/item/seeds/potatoseed = 3, + /obj/item/seeds/pumpkinseed = 3, + /obj/item/seeds/reishimycelium = 2, + /obj/item/seeds/riceseed = 3, + /obj/item/seeds/soyaseed = 3, + /obj/item/seeds/sugarcaneseed = 3, + /obj/item/seeds/sunflowerseed = 3, + /obj/item/seeds/shandseed = 2, + /obj/item/seeds/tobaccoseed = 3, + /obj/item/seeds/tomatoseed = 3, + /obj/item/seeds/towermycelium = 3, + /obj/item/seeds/watermelonseed = 3, + /obj/item/seeds/wheatseed = 3, + /obj/item/seeds/whitebeetseed = 3, + /obj/item/seeds/lavenderseed = 3 + ) /obj/machinery/seed_storage/attack_hand(mob/user as mob) user.set_machine(src) diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm index 9dfd3deb44..ada597f46b 100644 --- a/code/modules/mob/dead/observer/say.dm +++ b/code/modules/mob/dead/observer/say.dm @@ -11,9 +11,6 @@ src << "\red You cannot talk in deadchat (muted)." return - if (src.client.handle_spam_prevention(message,MUTE_DEADCHAT)) - return - . = src.say_dead(message) @@ -33,9 +30,6 @@ src << "\red You cannot emote in deadchat (muted)." return - if(src.client.handle_spam_prevention(message, MUTE_DEADCHAT)) - return - . = src.emote_dead(message) /* diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index 223b01e110..372409b443 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -10,8 +10,8 @@ var/speech_verb = "says" // 'says', 'hisses', 'farts'. var/ask_verb = "asks" // Used when sentence ends in a ? var/exclaim_verb = "exclaims" // Used when sentence ends in a ! - var/whisper_verb = "whispers" // Optional. When not specified speech_verb + quietly/softly is used instead. - var/signlang_verb = list("signs") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags + var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead. + var/signlang_verb = list("signs", "gestures") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags var/colour = "body" // CSS style to use for strings in this language. var/key = "x" // Character used to speak in language eg. :o for Unathi. var/flags = 0 // Various language flags. diff --git a/code/modules/mob/living/carbon/alien/emote.dm b/code/modules/mob/living/carbon/alien/emote.dm index 62fa2cf108..e31a293047 100644 --- a/code/modules/mob/living/carbon/alien/emote.dm +++ b/code/modules/mob/living/carbon/alien/emote.dm @@ -18,8 +18,6 @@ if (client.prefs.muted & MUTE_IC) src << "\red You cannot send IC messages (muted)." return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return if (stat) return if(!(message)) diff --git a/code/modules/mob/living/carbon/brain/emote.dm b/code/modules/mob/living/carbon/brain/emote.dm index f29167f1f3..5725dd4ec7 100644 --- a/code/modules/mob/living/carbon/brain/emote.dm +++ b/code/modules/mob/living/carbon/brain/emote.dm @@ -19,8 +19,6 @@ if (client.prefs.muted & MUTE_IC) src << "\red You cannot send IC messages (muted)." return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return if (stat) return if(!(message)) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 87c0524571..4488f65388 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -112,8 +112,6 @@ if (client.prefs.muted & MUTE_IC) src << "\red You cannot send IC messages (muted)." return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return if (stat) return if(!(message)) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index e0451046ae..01351dcf22 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -266,7 +266,6 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t UpdateDamageIcon() BITSET(hud_updateflag, HEALTH_HUD) updatehealth() - speech_problem_flag = 1 //Heal MANY external organs, in random order @@ -288,7 +287,6 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t parts -= picked updatehealth() BITSET(hud_updateflag, HEALTH_HUD) - speech_problem_flag = 1 if(update) UpdateDamageIcon() // damage MANY external organs, in random order diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 026bd9681e..e4a17174f8 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -71,8 +71,6 @@ var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life() - var/speech_problem_flag = 0 - var/miming = null //Toggle for the mime's abilities. var/special_voice = "" // For changing our voice. Used by a symptom. diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index a92509b1b1..117292ebaa 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -154,21 +154,6 @@ if(stat != CONSCIOUS) //Let's not worry about tourettes if you're not conscious. return - //Vision - if(species.vision_organ) - if(internal_organs_by_name[species.vision_organ]) // Vision organs cut out? Permablind. - eye_blind = 0 - blinded = 0 - eye_blurry = 0 - else - eye_blind = 1 - blinded = 1 - eye_blurry = 1 - else // Presumably if a species has no vision organs, they see via some other means. - eye_blind = 0 - blinded = 0 - eye_blurry = 0 - if (disabilities & EPILEPSY) if ((prob(1) && paralysis < 1)) src << "\red You have a seizure!" @@ -185,7 +170,6 @@ emote("cough") return if (disabilities & TOURETTES) - speech_problem_flag = 1 if ((prob(10) && paralysis <= 1)) Stun(10) spawn( 0 ) @@ -197,7 +181,6 @@ make_jittery(100) return if (disabilities & NERVOUS) - speech_problem_flag = 1 if (prob(10)) stuttering = max(10, stuttering) @@ -238,7 +221,6 @@ if(!gene.block) continue if(gene.is_active(src)) - speech_problem_flag = 1 gene.OnMobLife(src) radiation = Clamp(radiation,0,100) @@ -930,7 +912,6 @@ adjustHalLoss(-3) if(sleeping) - speech_problem_flag = 1 handle_dreams() if (mind) //Are they SSD? If so we'll keep them asleep but work off some of that sleep var in case of stoxin or similar. @@ -969,19 +950,18 @@ if(species.vision_organ) vision = internal_organs_by_name[species.vision_organ] - if(!vision) // Presumably if a species has no vision organs, they see via some other means. + if(!species.vision_organ) // Presumably if a species has no vision organs, they see via some other means. eye_blind = 0 blinded = 0 eye_blurry = 0 - else if(vision.is_broken()) // Vision organs cut out or broken? Permablind. + else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind. eye_blind = 1 blinded = 1 eye_blurry = 1 - else - //blindness - if(sdisabilities & BLIND) // Disabled-blind, doesn't get better on its own + else //You have the requisite organs + if(sdisabilities & BLIND) // Disabled-blind, doesn't get better on its own blinded = 1 - else if(eye_blind) // Blindness, heals slowly over time + else if(eye_blind) // Blindness, heals slowly over time eye_blind = max(eye_blind-1,0) blinded = 1 else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster @@ -1584,9 +1564,6 @@ if(stat == DEAD) holder.icon_state = "huddead" holder2.icon_state = "huddead" - else if(status_flags & XENO_HOST) - holder.icon_state = "hudxeno" - holder2.icon_state = "hudxeno" else if(foundVirus) holder.icon_state = "hudill" else if(has_brain_worms()) @@ -1682,28 +1659,11 @@ hud_list[SPECIALROLE_HUD] = holder hud_updateflag = 0 -/mob/living/carbon/human/handle_silent() - if(..()) - speech_problem_flag = 1 - return silent - -/mob/living/carbon/human/handle_slurring() - if(..()) - speech_problem_flag = 1 - return slurring - /mob/living/carbon/human/handle_stunned() if(!can_feel_pain()) stunned = 0 return 0 - if(..()) - speech_problem_flag = 1 - return stunned - -/mob/living/carbon/human/handle_stuttering() - if(..()) - speech_problem_flag = 1 - return stuttering + return ..() /mob/living/carbon/human/handle_fire() if(..()) diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index cbfb88676a..c87338d26c 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -1,10 +1,10 @@ -/mob/living/carbon/human/say(var/message) +/mob/living/carbon/human/say(var/message,var/whispering=0) var/alt_name = "" if(name != GetVoice()) alt_name = "(as [get_id_name("Unknown")])" message = sanitize(message) - ..(message, alt_name = alt_name) + ..(message, alt_name = alt_name, whispering = whispering) /mob/living/carbon/human/proc/forcesay(list/append) if(stat == CONSCIOUS) @@ -125,29 +125,20 @@ return verb -/mob/living/carbon/human/handle_speech_problems(var/message, var/verb) +/mob/living/carbon/human/handle_speech_problems(var/list/message_data) if(silent || (sdisabilities & MUTE)) - message = "" - speech_problem_flag = 1 + message_data[1] = "" + . = 1 + else if(istype(wear_mask, /obj/item/clothing/mask)) var/obj/item/clothing/mask/M = wear_mask if(M.voicechange) - message = pick(M.say_messages) - verb = pick(M.say_verbs) - speech_problem_flag = 1 + message_data[1] = pick(M.say_messages) + message_data[2] = pick(M.say_verbs) + . = 1 - if(message != "") - var/list/parent = ..() - message = parent[1] - verb = parent[2] - if(parent[3]) - speech_problem_flag = 1 - - var/list/returns[3] - returns[1] = message - returns[2] = verb - returns[3] = speech_problem_flag - return returns + else + . = ..(message_data) /mob/living/carbon/human/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name) switch(message_mode) @@ -190,9 +181,6 @@ if(has_radio) R.talk_into(src,message,null,verb,speaking) used_radios += R - if("whisper") - whisper_say(message, speaking, alt_name) - return 1 else if(message_mode) if(l_ear && istype(l_ear,/obj/item/device/radio)) diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index d0739809d0..0bd8a39c47 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -152,7 +152,7 @@ the secrets of their empire to their allies." num_alternate_languages = 2 secondary_langs = list("Skrellian", "Schechi") - name_language = null + name_language = "Skrellian" min_age = 19 max_age = 80 diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm deleted file mode 100644 index 8a233effd7..0000000000 --- a/code/modules/mob/living/carbon/human/whisper.dm +++ /dev/null @@ -1,155 +0,0 @@ -//Lallander was here -/mob/living/carbon/human/whisper(message as text) - var/alt_name = "" - - if(say_disabled) //This is here to try to identify lag problems - usr << "\red Speech is currently admin-disabled." - return - - message = sanitize(message) - log_whisper("[src.name]/[src.key] : [message]") - - if (src.client) - if (src.client.prefs.muted & MUTE_IC) - src << "\red You cannot whisper (muted)." - return - - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return - - if (src.stat == 2) - return src.say_dead(message) - - if (src.stat) - return - - if(name != GetVoice()) - alt_name = "(as [get_id_name("Unknown")])" - - //parse the language code and consume it - var/datum/language/speaking = parse_language(message) - if (speaking) - message = copytext(message,2+length(speaking.key)) - - whisper_say(message, speaking, alt_name) - - -//This is used by both the whisper verb and human/say() to handle whispering -/mob/living/carbon/human/proc/whisper_say(var/message, var/datum/language/speaking = null, var/alt_name="", var/verb="whispers") - - if (is_muzzled()) - src << "You're muzzled and cannot speak!" - return - - var/message_range = 1 - var/eavesdropping_range = 2 - var/watching_range = 5 - var/italics = 1 - - var/not_heard //the message displayed to people who could not hear the whispering - if (speaking) - if (speaking.whisper_verb) - verb = speaking.whisper_verb - not_heard = "[verb] something" - else - var/adverb = pick("quietly", "softly") - verb = "[speaking.speech_verb] [adverb]" - not_heard = "[speaking.speech_verb] something [adverb]" - else - not_heard = "[verb] something" //TODO get rid of the null language and just prevent speech if language is null - - message = capitalize(trim(message)) - - if(speech_problem_flag) - var/list/handle_r = handle_speech_problems(message) - message = handle_r[1] - verb = handle_r[2] - if(verb == "yells loudly") - verb = "slurs emphatically" - else - var/adverb = pick("quietly", "softly") - verb = "[verb] [adverb]" - - speech_problem_flag = handle_r[3] - - if(!message || message=="") - return - - //looks like this only appears in whisper. Should it be elsewhere as well? Maybe handle_speech_problems? - var/voice_sub - if(istype(back,/obj/item/weapon/rig)) - var/obj/item/weapon/rig/rig = back - // todo: fix this shit - if(rig.speech && rig.speech.voice_holder && rig.speech.voice_holder.active && rig.speech.voice_holder.voice) - voice_sub = rig.speech.voice_holder.voice - else - for(var/obj/item/gear in list(wear_mask,wear_suit,head)) - if(!gear) - continue - var/obj/item/voice_changer/changer = locate() in gear - if(changer && changer.active && changer.voice) - voice_sub = changer.voice - - if(voice_sub == "Unknown") - if(copytext(message, 1, 2) != "*") - var/list/temp_message = splittext(message, " ") - var/list/pick_list = list() - for(var/i = 1, i <= temp_message.len, i++) - pick_list += i - for(var/i=1, i <= abs(temp_message.len/3), i++) - var/H = pick(pick_list) - if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue - temp_message[H] = ninjaspeak(temp_message[H]) - pick_list -= H - message = jointext(temp_message, " ") - message = replacetext(message, "o", "¤") - message = replacetext(message, "p", "þ") - message = replacetext(message, "l", "£") - message = replacetext(message, "s", "§") - message = replacetext(message, "u", "µ") - message = replacetext(message, "b", "ß") - - var/list/listening = get_mobs_or_objects_in_view(message_range, src) - listening |= src - - //ghosts - for (var/mob/M in dead_mob_list) - if (!(M.client)) - continue - if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears)) - listening |= M - - //pass on the message to objects that can hear us. - for (var/obj/O in listening) - spawn (0) - if (O) - O.hear_talk(src, message, verb, speaking) - - var/list/eavesdropping = hearers(eavesdropping_range, src) - eavesdropping -= src - eavesdropping -= listening - - var/list/watching = hearers(watching_range, src) - watching -= src - watching -= listening - watching -= eavesdropping - - //now mobs - var/speech_bubble_test = say_test(message) - var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]") - spawn(30) qdel(speech_bubble) - - for(var/mob/M in listening) - M << speech_bubble - M.hear_say(message, verb, speaking, alt_name, italics, src) - - if (eavesdropping.len) - var/new_message = stars(message) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less. - for(var/mob/M in eavesdropping) - M << speech_bubble - M.hear_say(new_message, verb, speaking, alt_name, italics, src) - - if (watching.len) - var/rendered = "[src.name] [not_heard]." - for (var/mob/M in watching) - M.show_message(rendered, 2) diff --git a/code/modules/mob/living/carbon/metroid/emote.dm b/code/modules/mob/living/carbon/metroid/emote.dm index a6ea5498cd..d82372e52f 100644 --- a/code/modules/mob/living/carbon/metroid/emote.dm +++ b/code/modules/mob/living/carbon/metroid/emote.dm @@ -18,8 +18,6 @@ if (client.prefs.muted & MUTE_IC) src << "\red You cannot send IC messages (muted)." return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return if (stat) return if(!(message)) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index ad87fc2c39..3c10a525d5 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -147,7 +147,7 @@ /mob/living/proc/handle_disabilities() //Eyes - if(disabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own + if(sdisabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own eye_blind = max(eye_blind, 1) else if(eye_blind) //blindness, heals slowly over time eye_blind = max(eye_blind-1,0) @@ -155,7 +155,7 @@ eye_blurry = max(eye_blurry-1, 0) //Ears - if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own + if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own setEarDamage(-1, max(ear_deaf, 1)) else // deafness heals slowly over time, unless ear_damage is over 100 diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 54af2697ec..a2355b1820 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -82,27 +82,31 @@ proc/get_radio_key_from_channel(var/channel) /mob/living/proc/get_default_language() return default_language -/mob/living/proc/handle_speech_problems(var/message, var/verb) - var/list/returns[3] - var/speech_problem_flag = 0 +//Takes a list of the form list(message, verb, whispering) and modifies it as needed +//Returns 1 if a speech problem was applied, 0 otherwise +/mob/living/proc/handle_speech_problems(var/list/message_data) + var/message = message_data[1] + var/verb = message_data[2] + var/whispering = message_data[3] + . = 0 if((HULK in mutations) && health >= 25 && length(message)) message = "[uppertext(message)]!!!" verb = pick("yells","roars","hollers") - speech_problem_flag = 1 + whispering = 0 + . = 1 if(slurring) message = slur(message) verb = pick("slobbers","slurs") - speech_problem_flag = 1 + . = 1 if(stuttering) message = stutter(message) verb = pick("stammers","stutters") - speech_problem_flag = 1 + . = 1 - returns[1] = message - returns[2] = verb - returns[3] = speech_problem_flag - return returns + message_data[1] = message + message_data[2] = verb + message_data[2] = whispering /mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name) if(message_mode == "intercom") @@ -124,33 +128,42 @@ proc/get_radio_key_from_channel(var/channel) return "asks" return verb -/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="") +/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/whispering = 0) + //If you're muted for IC chat if(client) - if(client.prefs.muted & MUTE_IC) - src << "\red You cannot speak in IC (Muted)." + if((client.prefs.muted & MUTE_IC) || say_disabled) + src << "You cannot speak in IC (Muted)." return + //Redirect to say_dead if talker is dead if(stat) - if(stat == 2) + if(stat == DEAD) return say_dead(message) return + //Parse the mode var/message_mode = parse_message_mode(message, "headset") + //Maybe they are using say/whisper to do a quick emote, so do those switch(copytext(message,1,2)) if("*") return emote(copytext(message,2)) if("^") return custom_emote(1, copytext(message,2)) - //parse the radio code and consume it + //Parse the radio code and consume it if (message_mode) if (message_mode == "headset") message = copytext(message,2) //it would be really nice if the parse procs could do this for us. + else if (message_mode == "whisper") + whispering = 1 + message_mode = null + message = copytext(message,3) else message = copytext(message,3) + //Clean up any remaining space on the left message = trim_left(message) - //parse the language code and consume it + //Parse the language code and consume it if(!speaking) speaking = parse_language(message) if(speaking) @@ -158,42 +171,72 @@ proc/get_radio_key_from_channel(var/channel) else speaking = get_default_language() - // This is broadcast to all mobs with the language, - // irrespective of distance or anything else. + //HIVEMIND languages always send to all people with that language if(speaking && (speaking.flags & HIVEMIND)) speaking.broadcast(src,trim(message)) return 1 - verb = say_quote(message, speaking) - + //Self explanatory. if(is_muzzled()) src << "You're muzzled and cannot speak!" return + //Clean up any remaining junk on the left like spaces. message = trim_left(message) + //Autohiss handles auto-rolling tajaran R's and unathi S's/Z's + message = handle_autohiss(message, speaking) + + //Whisper vars + var/w_scramble_range = 5 //The range at which you get ***as*th**wi**** + var/w_adverb //An adverb prepended to the verb in whispers + var/w_not_heard //The message for people in watching range + + //Handle language-specific verbs and adverb setup if necessary + if(!whispering) //Just doing normal 'say' (for now, may change below) + verb = say_quote(message, speaking) + else if(whispering && speaking.whisper_verb) //Language has defined whisper verb + verb = speaking.whisper_verb + w_not_heard = "[verb] something" + else //Whispering but language has no whisper verb, use say verb + w_adverb = pick("quietly", "softly") + verb = speaking.speech_verb + w_not_heard = "[speaking.speech_verb] something [w_adverb]" + + //For speech disorders (hulk, slurring, stuttering) if(!(speaking && (speaking.flags & NO_STUTTER))) - message = handle_autohiss(message, speaking) + var/list/message_data = list(message, verb, whispering) + if(handle_speech_problems(message_data)) + message = message_data[1] + whispering = message_data[3] - var/list/handle_s = handle_speech_problems(message, verb) - message = handle_s[1] - verb = handle_s[2] + if(verb != message_data[2]) //They changed our verb + if(whispering) + w_adverb = pick("quietly", "softly") + verb = message_data[2] + //Whisper may have adverbs, add those if one was set + if(w_adverb) verb = "[verb] [w_adverb]" + + //If something nulled or emptied the message, forget it if(!message || message == "") return 0 + //Radio message handling var/list/obj/item/used_radios = new - if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)) + if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, whispering)) return 1 + //For languages with actual speech sounds var/list/handle_v = handle_speech_sound() var/sound/speech_sound = handle_v[1] var/sound_vol = handle_v[2] - var/italics = 0 + //Default range and italics, may be overridden past here var/message_range = world.view + var/italics = 0 - //speaking into radios + //Speaking into radios if(used_radios.len) italics = 1 message_range = 1 @@ -208,9 +251,13 @@ proc/get_radio_key_from_channel(var/channel) if (speech_sound) sound_vol *= 0.5 - var/turf/T = get_turf(src) + //Set vars if we're still whispering by this point + if(whispering) + italics = 1 + message_range = 1 + sound_vol *= 0.5 - //handle nonverbal and sign languages here + //Handle nonverbal and sign languages here if (speaking) if (speaking.flags & NONVERBAL) if (prob(30)) @@ -219,55 +266,64 @@ proc/get_radio_key_from_channel(var/channel) if (speaking.flags & SIGNLANG) return say_signlang(message, pick(speaking.signlang_verb), speaking) + //These will contain the main receivers of the message var/list/listening = list() var/list/listening_obj = list() + //Atmosphere calculations (speaker's side only, for now) + var/turf/T = get_turf(src) if(T) - //make sure the air can transmit speech - speaker's side + //Air is too thin to carry sound at all, contact speech only var/datum/gas_mixture/environment = T.return_air() var/pressure = (environment)? environment.return_pressure() : 0 if(pressure < SOUND_MINIMUM_PRESSURE) message_range = 1 - if (pressure < ONE_ATMOSPHERE*0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet + //Air is nearing minimum levels, make text italics as a hint, and muffle sound + if (pressure < ONE_ATMOSPHERE*0.4) italics = 1 - sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact + sound_vol *= 0.5 - var/list/hear = get_mobs_or_objects_in_view(message_range,src) - var/list/hearturfs = list() - - for(var/I in hear) - if(ismob(I)) - var/mob/M = I - listening += M - hearturfs += M.locs[1] - else if(isobj(I)) - var/obj/O = I - hearturfs += O.locs[1] - listening_obj |= O - - - for(var/mob/M in player_list) - if(M.stat == DEAD && M.client && M.is_preference_enabled(/datum/client_preference/ghost_ears)) - listening |= M - continue - if(M.loc && M.locs[1] in hearturfs) - listening |= M + //Obtain the mobs and objects in the message range + var/list/results = get_mobs_and_objs_in_view_fast(T, world.view) + listening = results["mobs"] + listening_obj = results["objs"] + else + return 1 //If we're in nullspace, then forget it. + //The 'post-say' static speech bubble var/speech_bubble_test = say_test(message) var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]") spawn(30) qdel(speech_bubble) + //Main 'say' and 'whisper' message delivery for(var/mob/M in listening) - M << speech_bubble - M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol) + spawn(0) //Using spawns to queue all the messages for AFTER this proc is done, and stop runtimes + if(M && src) //If we still exist, when the spawn processes + var/dst = get_dist(get_turf(M),get_turf(src)) + + if(dst <= message_range || M.stat == DEAD) //Inside normal message range, or dead with ears (handled in the view proc) + M << speech_bubble + M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol) + + if(whispering) //Don't even bother with these unless whispering + if(dst > message_range && dst <= w_scramble_range) //Inside whisper scramble range + M << speech_bubble + M.hear_say(stars(message), verb, speaking, alt_name, italics, src, speech_sound, sound_vol*0.2) + if(dst > w_scramble_range && dst <= world.view) //Inside whisper 'visible' range + M.show_message("[src.name] [w_not_heard].", 2) + + //Object message delivery for(var/obj/O in listening_obj) spawn(0) - if(O) //It's possible that it could be deleted in the meantime. - O.hear_talk(src, message, verb, speaking) + if(O && src) //If we still exist, when the spawn processes + var/dst = get_dist(get_turf(O),get_turf(src)) + if(dst <= message_range) + O.hear_talk(src, message, verb, speaking) - log_say("[name]/[key] : [message]") + //Log the message to file + log_say("[name]/[key][whispering ? " (W)" : ""]: [message]") return 1 /mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_say.dm b/code/modules/mob/living/silicon/robot/drone/drone_say.dm index b0f89a70ea..5cdcd3dbd8 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_say.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_say.dm @@ -4,8 +4,6 @@ if(client.prefs.muted & MUTE_IC) src << "You cannot send IC messages (muted)." return 0 - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return 0 message = sanitize(message) diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index 23b6cc0d67..7f2102a860 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -14,8 +14,6 @@ if(client.prefs.muted & MUTE_IC) src << "You cannot send IC messages (muted)." return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return if (stat) return if(!(message)) diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index ece00da5ee..e2810ad641 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -1,5 +1,5 @@ -/mob/living/silicon/say(var/message, var/sanitize = 1) - return ..(sanitize ? sanitize(message) : message) +/mob/living/silicon/say(var/message, var/sanitize = 1, var/whispering = 0) + return ..((sanitize ? sanitize(message) : message), whispering = whispering) /mob/living/silicon/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name) log_say("[key_name(src)] : [message]") diff --git a/code/modules/mob/living/simple_animal/borer/borer_captive.dm b/code/modules/mob/living/simple_animal/borer/borer_captive.dm index 2d6bfc34b3..f07b9d32ce 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_captive.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_captive.dm @@ -9,8 +9,6 @@ if(client.prefs.muted & MUTE_IC) src << "\red You cannot speak in IC (muted)." return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return if(istype(src.loc,/mob/living/simple_animal/borer)) diff --git a/code/modules/mob/living/simple_animal/borer/say.dm b/code/modules/mob/living/simple_animal/borer/say.dm index 0d4cdad06e..e76a02a7e2 100644 --- a/code/modules/mob/living/simple_animal/borer/say.dm +++ b/code/modules/mob/living/simple_animal/borer/say.dm @@ -16,8 +16,6 @@ if(client.prefs.muted & MUTE_IC) src << "\red You cannot speak in IC (muted)." return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return if (copytext(message, 1, 2) == "*") return emote(copytext(message, 2)) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index ec47effaba..f7aaa52f78 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -1,29 +1,15 @@ /mob/proc/say() return -/mob/verb/whisper() +/mob/verb/whisper(message as text) set name = "Whisper" set category = "IC" - return + + usr.say(message,whispering=1) /mob/verb/say_verb(message as text) set name = "Say" set category = "IC" - if(say_disabled) //This is here to try to identify lag problems - usr << "\red Speech is currently admin-disabled." - return - //Let's try to make users fix their errors - we try to detect single, out-of-place letters and 'unintended' words - /* - var/first_letter = copytext(message,1,2) - if((copytext(message,2,3) == " " && first_letter != "I" && first_letter != "A" && first_letter != ";") || cmptext(copytext(message,1,5), "say ") || cmptext(copytext(message,1,4), "me ") || cmptext(copytext(message,1,6), "looc ") || cmptext(copytext(message,1,5), "ooc ") || cmptext(copytext(message,2,6), "say ")) - var/response = alert(usr, "Do you really want to say this using the *say* verb?\n\n[message]\n", "Confirm your message", "Yes", "Edit message", "No") - if(response == "Edit message") - message = input(usr, "Please edit your message carefully:", "Edit message", message) - if(!message) - return - else if(response == "No") - return - */ set_typing_indicator(0) usr.say(message) @@ -62,7 +48,7 @@ /mob/proc/say_understands(var/mob/other,var/datum/language/speaking = null) - if (src.stat == 2) //Dead + if (src.stat == DEAD) return 1 //Universal speak makes everything understandable, for obvious reasons. diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index f467cf4dd5..51ffc6f7b6 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -21,6 +21,27 @@ If d1 = 0 and d2 = dir, it's a O-X cable, getting from the center of the tile to If d1 = dir1 and d2 = dir2, it's a full X-X cable, getting from dir1 to dir2 By design, d1 is the smallest direction and d2 is the highest */ +var/list/possible_cable_coil_colours = list( + "White" = COLOR_WHITE, + "Silver" = COLOR_SILVER, + "Gray" = COLOR_GRAY, + "Black" = COLOR_BLACK, + "Red" = COLOR_RED, + "Maroon" = COLOR_MAROON, + "Yellow" = COLOR_YELLOW, + "Olive" = COLOR_OLIVE, + "Lime" = COLOR_GREEN, + "Green" = COLOR_LIME, + "Cyan" = COLOR_CYAN, + "Teal" = COLOR_TEAL, + "Blue" = COLOR_BLUE, + "Navy" = COLOR_NAVY, + "Pink" = COLOR_PINK, + "Purple" = COLOR_PURPLE, + "Orange" = COLOR_ORANGE, + "Beige" = COLOR_BEIGE, + "Brown" = COLOR_BROWN + ) /obj/structure/cable level = 1 @@ -464,6 +485,7 @@ obj/structure/cable/proc/cableColor(var/colorC) slot_flags = SLOT_BELT item_state = "coil" attack_verb = list("whipped", "lashed", "disciplined", "flogged") + stacktype = /obj/item/stack/cable_coil /obj/item/stack/cable_coil/cyborg name = "cable coil synthesizer" @@ -472,7 +494,6 @@ obj/structure/cable/proc/cableColor(var/colorC) matter = null uses_charge = 1 charge_costs = list(1) - stacktype = /obj/item/stack/cable_coil /obj/item/stack/cable_coil/suicide_act(mob/user) if(locate(/obj/item/weapon/stool) in user.loc) @@ -531,6 +552,17 @@ obj/structure/cable/proc/cableColor(var/colorC) icon_state = "coil" name = "cable coil" +/obj/item/stack/cable_coil/proc/set_cable_color(var/selected_color, var/user) + if(!selected_color) + return + + var/final_color = possible_cable_coil_colours[selected_color] + if(!final_color) + final_color = possible_cable_coil_colours["Red"] + selected_color = "red" + color = final_color + user << "You change \the [src]'s color to [lowertext(selected_color)]." + /obj/item/stack/cable_coil/proc/update_wclass() if(amount == 1) w_class = 1.0 @@ -571,42 +603,17 @@ obj/structure/cable/proc/cableColor(var/colorC) set name = "Change Colour" set category = "Object" - var/list/possible_colours = list ("Yellow", "Green", "Pink", "Blue", "Orange", "Cyan", "Red") - var/selected_type = input("Pick new colour.", "Cable Colour", null, null) as null|anything in possible_colours - - if(selected_type) - switch(selected_type) - if("Yellow") - color = COLOR_YELLOW - if("Green") - color = COLOR_LIME - if("Pink") - color = COLOR_PINK - if("Blue") - color = COLOR_BLUE - if("Orange") - color = COLOR_ORANGE - if("Cyan") - color = COLOR_CYAN - else - color = COLOR_RED - usr << "You change your cable coil's colour to [selected_type]" + var/selected_type = input("Pick new colour.", "Cable Colour", null, null) as null|anything in possible_cable_coil_colours + set_cable_color(selected_type, usr) // Items usable on a cable coil : // - Wirecutters : cut them duh ! // - Cable coil : merge cables -/obj/item/stack/cable_coil/proc/can_merge(var/obj/item/stack/cable_coil/C) - return color == C.color - -/obj/item/stack/cable_coil/cyborg/can_merge() - return 1 /obj/item/stack/cable_coil/transfer_to(obj/item/stack/cable_coil/S) if(!istype(S)) + world << 1 return - if(!can_merge(S)) - return - ..() /obj/item/stack/cable_coil/use() @@ -880,7 +887,51 @@ obj/structure/cable/proc/cableColor(var/colorC) stacktype = /obj/item/stack/cable_coil color = COLOR_WHITE +/obj/item/stack/cable_coil/silver + stacktype = /obj/item/stack/cable_coil + color = COLOR_SILVER + +/obj/item/stack/cable_coil/gray + stacktype = /obj/item/stack/cable_coil + color = COLOR_GRAY + +/obj/item/stack/cable_coil/black + stacktype = /obj/item/stack/cable_coil + color = COLOR_BLACK + +/obj/item/stack/cable_coil/maroon + stacktype = /obj/item/stack/cable_coil + color = COLOR_MAROON + +/obj/item/stack/cable_coil/olive + stacktype = /obj/item/stack/cable_coil + color = COLOR_OLIVE + +/obj/item/stack/cable_coil/lime + stacktype = /obj/item/stack/cable_coil + color = COLOR_LIME + +/obj/item/stack/cable_coil/teal + stacktype = /obj/item/stack/cable_coil + color = COLOR_TEAL + +/obj/item/stack/cable_coil/navy + stacktype = /obj/item/stack/cable_coil + color = COLOR_NAVY + +/obj/item/stack/cable_coil/purple + stacktype = /obj/item/stack/cable_coil + color = COLOR_PURPLE + +/obj/item/stack/cable_coil/beige + stacktype = /obj/item/stack/cable_coil + color = COLOR_BEIGE + +/obj/item/stack/cable_coil/brown + stacktype = /obj/item/stack/cable_coil + color = COLOR_BROWN + /obj/item/stack/cable_coil/random/New() stacktype = /obj/item/stack/cable_coil - color = pick(COLOR_RED, COLOR_BLUE, COLOR_LIME, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN) + color = pick(COLOR_RED, COLOR_BLUE, COLOR_LIME, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN, COLOR_SILVER, COLOR_GRAY, COLOR_BLACK, COLOR_MAROON, COLOR_OLIVE, COLOR_LIME, COLOR_TEAL, COLOR_NAVY, COLOR_PURPLE, COLOR_BEIGE, COLOR_BROWN) ..() \ No newline at end of file diff --git a/code/modules/projectiles/targeting/targeting_overlay.dm b/code/modules/projectiles/targeting/targeting_overlay.dm index b0577bdf5f..8c87751de7 100644 --- a/code/modules/projectiles/targeting/targeting_overlay.dm +++ b/code/modules/projectiles/targeting/targeting_overlay.dm @@ -23,7 +23,6 @@ owner = newowner loc = null verbs.Cut() - toggle_permission(TARGET_CAN_RADIO) /obj/aiming_overlay/proc/toggle_permission(var/perm) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index be96e6665a..469c34a1c1 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -548,6 +548,20 @@ cup_name = "cup of milk" cup_desc = "White and nutritious goodness!" +/datum/reagent/drink/milk/chocolate + name = "Chocolate Milk" + id = "chocolate_milk" + description = "A delicious mixture of perfectly healthy mix and terrible chocolate." + color = "#74533b" + + glass_icon_state = "glass_brown" + glass_name = "glass of chocolate milk" + glass_desc = "Delciously fattening!" + + cup_icon_state = "cup_brown" + cup_name = "cup of chocolate milk" + cup_desc = "Deliciously fattening!" + /datum/reagent/drink/milk/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) ..() if(alien == IS_DIONA) diff --git a/code/modules/reagents/reagent_containers/food/drinks.dm b/code/modules/reagents/reagent_containers/food/drinks.dm index c934343e77..3b78dc7326 100644 --- a/code/modules/reagents/reagent_containers/food/drinks.dm +++ b/code/modules/reagents/reagent_containers/food/drinks.dm @@ -123,6 +123,23 @@ ..() reagents.add_reagent("soymilk", 50) +/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton + name = "Small Carton of Milk" + volume = 30 + icon_state = "mini-milk" +/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/New() + ..() + reagents.add_reagent("milk", 30) + +/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate + name = "Small Carton of Chocolate Milk" + desc = "It's milk! This one is in delicious chocolate flavour." + +/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate/New() + ..() + reagents.add_reagent("chocolate_milk", 30) + + /obj/item/weapon/reagent_containers/food/drinks/coffee name = "Robust Coffee" desc = "Careful, the beverage you're about to enjoy is extremely hot." diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm index a9e55b26fe..712772a54b 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm @@ -40,7 +40,7 @@ if(!isGlass || !smash_duration) return 0 - var/list/chance_table = list(90, 90, 85, 85, 60, 35, 15) //starting from distance 0 + var/list/chance_table = list(100, 95, 90, 85, 75, 55, 35) //starting from distance 0 var/idx = max(distance + 1, 1) //since list indices start at 1 if(idx > chance_table.len) return 0 diff --git a/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm b/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm index cdf495405f..b10feb2b59 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm @@ -133,3 +133,46 @@ name = "shot glass of " + reagents.get_master_reagent_name() //No matter what, the glass will tell you the reagent's name. Might be too abusable in the future. else name = "shot glass" + +/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask + name = "fitness shaker" + desc = "Big enough to contain enough protein to get perfectly swole. Don't mind the bits." + icon_state = "fitness-cup_black" + volume = 100 + matter = list("plastic" = 2000) + +/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/New() + ..() + icon_state = pick("fitness-cup_black", "fitness-cup_red", "fitness-cup_black") + +/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/on_reagent_change() + overlays.Cut() + + if(reagents.total_volume) + var/image/filling = image('icons/obj/reagentfillings.dmi', src, "fitness-cup10") + + switch(reagents.total_volume) + if(0 to 10) filling.icon_state = "fitness-cup10" + if(11 to 20) filling.icon_state = "fitness-cup20" + if(21 to 29) filling.icon_state = "fitness-cup30" + if(30 to 39) filling.icon_state = "fitness-cup40" + if(40 to 49) filling.icon_state = "fitness-cup50" + if(50 to 59) filling.icon_state = "fitness-cup60" + if(60 to 69) filling.icon_state = "fitness-cup70" + if(70 to 79) filling.icon_state = "fitness-cup80" + if(80 to 89) filling.icon_state = "fitness-cup90" + if(90 to INFINITY) filling.icon_state = "fitness-cup100" + + filling.color += reagents.get_color() + overlays += filling + +/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/proteinshake + name = "protein shake" + +/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/fitnessflask/proteinshake/New() + ..() + reagents.add_reagent("nutriment", 30) + reagents.add_reagent("iron", 10) + reagents.add_reagent("protein", 15) + reagents.add_reagent("water", 45) + on_reagent_change() \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 98ce8751aa..854e6b7281 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -273,6 +273,19 @@ reagents.add_reagent("sugar", 3) bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar + name = "protein bar" + desc = "SwoleMAX brand protein bars, guaranteed to get you feeling perfectly overconfident." + icon_state = "proteinbar" + trash = /obj/item/trash/candy/proteinbar + +/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar/New() + ..() + reagents.add_reagent("nutriment", 9) + reagents.add_reagent("protein", 4) + reagents.add_reagent("sugar", 4) + bitesize = 6 + /obj/item/weapon/reagent_containers/food/snacks/candy/donor name = "Donor Candy" desc = "A little treat for blood donors." diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 89598898f8..9e22362872 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -294,3 +294,12 @@ /obj/item/weapon/reagent_containers/pill/spaceacillin/New() ..() reagents.add_reagent("spaceacillin", 15) + +/obj/item/weapon/reagent_containers/pill/diet + name = "diet pill" + desc = "Guaranteed to get you slim!" + icon_state = "pill9" + +/obj/item/weapon/reagent_containers/pill/diet/New() + ..() + reagents.add_reagent("lipozine", 2) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 7c291f1906..3c51df071e 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -344,3 +344,12 @@ reagents.add_reagent("chloralhydrate", 50) mode = SYRINGE_INJECT update_icon() + +/obj/item/weapon/reagent_containers/syringe/steroid + name = "Syringe (anabolic steroids)" + desc = "Contains drugs for muscle growth." + +/obj/item/weapon/reagent_containers/syringe/steroid/New() + ..() + reagents.add_reagent("adrenaline",5) + reagents.add_reagent("hyperzine",10) diff --git a/code/modules/spells/spellbook.dm b/code/modules/spells/spellbook.dm index 822bc8da7c..b54b243609 100644 --- a/code/modules/spells/spellbook.dm +++ b/code/modules/spells/spellbook.dm @@ -42,8 +42,6 @@ This spell temporarly blinds a single person and does not require wizard garb.
Subjugation (30)
This spell temporarily subjugates a target's mind and does not require wizard garb.
- Mind Transfer (60)
- This spell allows the user to switch bodies with a target. Careful to not lose your memory in the process.
Forcewall (10)
This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb.
Blink (2)
@@ -56,8 +54,6 @@ This spell creates your ethereal form, temporarily making you invisible and able to pass through walls.
Knock (10)
This spell opens nearby doors and does not require wizard garb.
- Curse of the Horseman (15)
- This spell will curse a person to wear an unremovable horse mask (it has glue on the inside) and speak like a horse. It does not require wizard garb.
Remove Clothes Requirement Warning: this takes away 2 spell choices.

Artefacts:
@@ -174,10 +170,10 @@ feedback_add_details("wizard_spell_learned","SJ") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.add_spell(new/spell/targeted/subjugation) temp = "You have learned subjugate." - if("mindswap") - feedback_add_details("wizard_spell_learned","MT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.add_spell(new/spell/targeted/mind_transfer) - temp = "You have learned mindswap." +// if("mindswap") +// feedback_add_details("wizard_spell_learned","MT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells +// H.add_spell(new/spell/targeted/mind_transfer) +// temp = "You have learned mindswap." if("forcewall") feedback_add_details("wizard_spell_learned","FW") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.add_spell(new/spell/aoe_turf/conjure/forcewall) @@ -202,10 +198,10 @@ feedback_add_details("wizard_spell_learned","KN") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells H.add_spell(new/spell/aoe_turf/knock) temp = "You have learned knock." - if("horseman") - feedback_add_details("wizard_spell_learned","HH") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.add_spell(new/spell/targeted/equip_item/horsemask) - temp = "You have learned curse of the horseman." +// if("horseman") +// feedback_add_details("wizard_spell_learned","HH") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells +// H.add_spell(new/spell/targeted/equip_item/horsemask) +// temp = "You have learned curse of the horseman." if("mentalfocus") feedback_add_details("wizard_spell_learned","MF") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells new /obj/item/weapon/gun/energy/staff/focus(get_turf(H)) diff --git a/html/changelog.html b/html/changelog.html index 8a5a9b6746..82e7175c06 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,19 @@ -->
+

25 May 2016

+

Serithi updated:

+ +

Yoshax updated:

+ +

17 May 2016

SilveryFerret updated: