From 981b76832098adaf761adcc65178df32bd4744d0 Mon Sep 17 00:00:00 2001 From: Cameron653 Date: Fri, 16 Mar 2018 13:35:20 -0400 Subject: [PATCH 01/74] Makes a failsafe drink overdose proc --- .../Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 8695f36c51f..2dddebe9e28 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -450,6 +450,9 @@ if(adj_temp < 0 && M.bodytemperature > 310) M.bodytemperature = min(310, M.bodytemperature - (adj_temp * TEMPERATURE_DAMAGE_COEFFICIENT)) +/datum/reagent/drink/overdose(var/mob/living/carbon/M, var/alien) //Added this is a failsafe, as coffee milkshakes were FUCKING KILLING PEOPLE + M.make_jittery(5) + // Juices /datum/reagent/drink/juice/banana @@ -2844,4 +2847,4 @@ adj_temp = -5 glass_name = "Mint Julep" - glass_desc = "Minty and refreshing, perfect for a hot day." \ No newline at end of file + glass_desc = "Minty and refreshing, perfect for a hot day." From 36097cb31d88816371523c4a754d21dda5272ed9 Mon Sep 17 00:00:00 2001 From: Cameron653 Date: Sat, 17 Mar 2018 00:52:07 -0400 Subject: [PATCH 02/74] Changes --- .../Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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 2dddebe9e28..853fe1cab02 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -450,8 +450,8 @@ if(adj_temp < 0 && M.bodytemperature > 310) M.bodytemperature = min(310, M.bodytemperature - (adj_temp * TEMPERATURE_DAMAGE_COEFFICIENT)) -/datum/reagent/drink/overdose(var/mob/living/carbon/M, var/alien) //Added this is a failsafe, as coffee milkshakes were FUCKING KILLING PEOPLE - M.make_jittery(5) +/datum/reagent/drink/overdose(var/mob/living/carbon/M, var/alien) //Add special interactions here in the future if desired. + ..() // Juices @@ -1047,11 +1047,14 @@ adj_dizzy = -5 adj_drowsy = -3 adj_sleepy = -2 - overdose = 45 + glass_name = "Coffee Milkshake" glass_desc = "An energizing coffee milkshake, perfect for hot days at work.." +/datum/reagent/drink/milkshake/coffeeshake/overdose(var/mob/living/carbon/M, var/alien) + M.make_jittery(5) + /datum/reagent/drink/rewriter name = "Rewriter" id = "rewriter" From bf3ecf46e6b63fe8b06ee47615173518e140a374 Mon Sep 17 00:00:00 2001 From: Billy Bangles Date: Mon, 19 Mar 2018 15:26:11 -0400 Subject: [PATCH 03/74] adds snow footstep noises and also nerfs ice while i'm at it --- code/game/turfs/flooring/flooring.dm | 7 +++++++ code/game/turfs/simulated/outdoors/snow.dm | 4 +++- sound/effects/footstep/snow1.ogg | Bin 0 -> 13992 bytes sound/effects/footstep/snow2.ogg | Bin 0 -> 13114 bytes sound/effects/footstep/snow3.ogg | Bin 0 -> 10534 bytes sound/effects/footstep/snow4.ogg | Bin 0 -> 9760 bytes sound/effects/footstep/snow5.ogg | Bin 0 -> 10600 bytes 7 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 sound/effects/footstep/snow1.ogg create mode 100644 sound/effects/footstep/snow2.ogg create mode 100644 sound/effects/footstep/snow3.ogg create mode 100644 sound/effects/footstep/snow4.ogg create mode 100644 sound/effects/footstep/snow5.ogg diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index ed1600f26f8..c845657c74c 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -67,6 +67,13 @@ var/list/flooring_types desc = "A layer of many tiny bits of frozen water. It's hard to tell how deep it is." icon = 'icons/turf/snow_new.dmi' icon_base = "snow" + footstep_sounds = list("human" = list( + 'sound/effects/footstep/snow1.ogg', + 'sound/effects/footstep/snow2.ogg', + 'sound/effects/footstep/snow3.ogg', + 'sound/effects/footstep/snow4.ogg', + 'sound/effects/footstep/snow5.ogg')) + /decl/flooring/snow/snow2 name = "snow" diff --git a/code/game/turfs/simulated/outdoors/snow.dm b/code/game/turfs/simulated/outdoors/snow.dm index 9926c4704ad..5fed8af66ba 100644 --- a/code/game/turfs/simulated/outdoors/snow.dm +++ b/code/game/turfs/simulated/outdoors/snow.dm @@ -3,12 +3,14 @@ icon_state = "snow" edge_blending_priority = 6 movement_cost = 2 + initial_flooring = /decl/flooring/snow turf_layers = list( /turf/simulated/floor/outdoors/rocks, /turf/simulated/floor/outdoors/dirt ) var/list/crossed_dirs = list() + /turf/simulated/floor/outdoors/snow/Entered(atom/A) if(isliving(A)) var/mdir = "[A.dir]" @@ -51,5 +53,5 @@ if(istype(M, /mob/living)) if(M.stunned == 0) to_chat(M, "You slide across the ice!") - M.SetStunned(2) + M.SetStunned(1) step(M,M.dir) diff --git a/sound/effects/footstep/snow1.ogg b/sound/effects/footstep/snow1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..e98e6df420c1f1e52adc1d74093c9832a08c7db3 GIT binary patch literal 13992 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 A3IG5A literal 0 HcmV?d00001 diff --git a/sound/effects/footstep/snow2.ogg b/sound/effects/footstep/snow2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..e4e2058e50c2b742c7661d12184807973ae014c8 GIT binary patch literal 13114 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 QbR>8qa=G>NC41oi0PF>zZvX%Q literal 0 HcmV?d00001 diff --git a/sound/effects/footstep/snow3.ogg b/sound/effects/footstep/snow3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1a6e23b6c39554e9b6b5cea9e01d3a1b8303a9ce GIT binary patch literal 10534 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 literal 0 HcmV?d00001 diff --git a/sound/effects/footstep/snow4.ogg b/sound/effects/footstep/snow4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9cc98e830e338871e24f4218675342c67398725d GIT binary patch literal 9760 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 atm*H6$Ub)B?%-wDUlKY?2A+H9K>r7fMz!kz literal 0 HcmV?d00001 From 05fd53ebccf2e4f2be0b60f405bff8d200c0b72d Mon Sep 17 00:00:00 2001 From: Billy Bangles Date: Mon, 19 Mar 2018 20:20:31 -0400 Subject: [PATCH 04/74] adds permanent markers also tweaks paint recipe to use ink instead of crayons. --- code/datums/supplypacks/recreation.dm | 1 + code/game/objects/items/crayons.dm | 104 ++++++++++++++++-- .../objects/items/weapons/storage/fancy.dm | 48 +++++++- code/modules/paperwork/pen.dm | 21 ++-- .../Chemistry-Reagents-Other.dm | 54 +++++++++ code/modules/reagents/Chemistry-Recipes.dm | 16 +-- html/changelogs/Billybangles - Markers.yml | 38 +++++++ icons/obj/crayons.dmi | Bin 732 -> 5079 bytes 8 files changed, 256 insertions(+), 26 deletions(-) create mode 100644 html/changelogs/Billybangles - Markers.yml diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm index 7bfdaaeeb68..7f801ea1b36 100644 --- a/code/datums/supplypacks/recreation.dm +++ b/code/datums/supplypacks/recreation.dm @@ -39,6 +39,7 @@ name = "Arts and Crafts supplies" contains = list( /obj/item/weapon/storage/fancy/crayons, + /obj/item/weapon/storage/fancy/markers, /obj/item/device/camera, /obj/item/device/camera_film = 2, /obj/item/weapon/storage/photo_album, diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 31bb9160f83..2ad51ca887a 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -46,11 +46,11 @@ if(colour != "#FFFFFF" && shadeColour != "#000000") colour = "#FFFFFF" shadeColour = "#000000" - user << "You will now draw in white and black with this crayon." + to_chat(usr,"You will now draw in white and black with this crayon.") else colour = "#000000" shadeColour = "#FFFFFF" - user << "You will now draw in black and white with this crayon." + to_chat(usr,"You will now draw in black and white with this crayon.") return /obj/item/weapon/pen/crayon/rainbow @@ -72,22 +72,22 @@ switch(drawtype) if("letter") drawtype = input("Choose the letter.", "Crayon scribbles") in list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z") - user << "You start drawing a letter on the [target.name]." + to_chat(usr,"You start drawing a letter on the [target.name].") if("graffiti") - user << "You start drawing graffiti on the [target.name]." + to_chat(usr,"You start drawing graffiti on the [target.name].") if("rune") - user << "You start drawing a rune on the [target.name]." + to_chat(usr,"You start drawing a rune on the [target.name].") if("arrow") drawtype = input("Choose the arrow.", "Crayon scribbles") in list("left", "right", "up", "down") - user << "You start drawing an arrow on the [target.name]." + to_chat(usr,"You start drawing an arrow on the [target.name].") if(instant || do_after(user, 50)) new /obj/effect/decal/cleanable/crayon(target,colour,shadeColour,drawtype) - user << "You finish drawing." + to_chat(usr,"You finish drawing.") target.add_fingerprint(user) // Adds their fingerprints to the floor the crayon is drawn on. if(uses) uses-- if(!uses) - user << "You used up your crayon!" + to_chat(usr,"You used up your crayon!") qdel(src) return @@ -99,7 +99,93 @@ if(uses) uses -= 5 if(uses <= 0) - user << "You ate your crayon!" + to_chat(user,"You ate your crayon!") qdel(src) else ..() + +/obj/item/weapon/pen/crayon/marker/black + icon_state = "markerblack" + colour = "#2D2D2D" + shadeColour = "#000000" + colourName = "black" + +/obj/item/weapon/pen/crayon/marker/red + icon_state = "markerred" + colour = "#DA0000" + shadeColour = "#810C0C" + colourName = "red" + +/obj/item/weapon/pen/crayon/marker/orange + icon_state = "markerorange" + colour = "#FF9300" + shadeColour = "#A55403" + colourName = "orange" + +/obj/item/weapon/pen/crayon/marker/yellow + icon_state = "markeryellow" + colour = "#FFF200" + shadeColour = "#886422" + colourName = "yellow" + +/obj/item/weapon/pen/crayon/marker/green + icon_state = "markergreen" + colour = "#A8E61D" + shadeColour = "#61840F" + colourName = "green" + +/obj/item/weapon/pen/crayon/marker/blue + icon_state = "markerblue" + colour = "#00B7EF" + shadeColour = "#0082A8" + colourName = "blue" + +/obj/item/weapon/pen/crayon/marker/purple + icon_state = "markerpurple" + colour = "#DA00FF" + shadeColour = "#810CFF" + colourName = "purple" + +/obj/item/weapon/pen/crayon/marker/mime + icon_state = "markermime" + desc = "A very sad-looking marker." + colour = "#FFFFFF" + shadeColour = "#000000" + colourName = "mime" + uses = 0 + +/obj/item/weapon/pen/crayon/marker/mime/attack_self(mob/living/user as mob) //inversion + if(colour != "#FFFFFF" && shadeColour != "#000000") + colour = "#FFFFFF" + shadeColour = "#000000" + to_chat(usr,"You will now draw in white and black with this marker.") + else + colour = "#000000" + shadeColour = "#FFFFFF" + to_chat(usr,"You will now draw in black and white with this marker.") + return + +/obj/item/weapon/pen/crayon/marker/rainbow + icon_state = "markerrainbow" + colour = "#FFF000" + shadeColour = "#000FFF" + colourName = "rainbow" + uses = 0 + +/obj/item/weapon/pen/crayon/marker/rainbow/attack_self(mob/living/user as mob) + colour = input(user, "Please select the main colour.", "Marker colour") as color + shadeColour = input(user, "Please select the shade colour.", "Marker colour") as color + return + +/obj/item/weapon/pen/crayon/marker/attack(mob/M as mob, mob/user as mob) + if(M == user) + to_chat(usr,"You take a bite of the marker and swallow it.") + user.nutrition += 1 + user.reagents.add_reagent("marker_ink",6) + if(uses) + uses -= 5 + if(uses <= 0) + to_chat(user,"You ate the marker!") + qdel(src) + else + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index c390cb0abd9..fc34e0999d2 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -114,6 +114,48 @@ return ..() +/obj/item/weapon/storage/fancy/markers + name = "box of markers" + desc = "A very professional looking box of permanent markers." + icon = 'icons/obj/crayons.dmi' + icon_state = "markerbox" + w_class = ITEMSIZE_SMALL + icon_type = "marker" + can_hold = list( + /obj/item/weapon/pen/crayon/marker + ) + starts_with = list( + /obj/item/weapon/pen/crayon/marker/black, + /obj/item/weapon/pen/crayon/marker/red, + /obj/item/weapon/pen/crayon/marker/orange, + /obj/item/weapon/pen/crayon/marker/yellow, + /obj/item/weapon/pen/crayon/marker/green, + /obj/item/weapon/pen/crayon/marker/blue, + /obj/item/weapon/pen/crayon/marker/purple + ) + +/obj/item/weapon/storage/fancy/markers/initialize() + . = ..() + update_icon() + +/obj/item/weapon/storage/fancy/markers/update_icon() + var/mutable_appearance/ma = new(src) + ma.overlays = list() + for(var/obj/item/weapon/pen/crayon/marker/marker in contents) + ma.overlays += image('icons/obj/crayons.dmi',"m"+marker.colourName) + appearance = ma + +/obj/item/weapon/storage/fancy/markers/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W,/obj/item/weapon/pen/crayon/marker)) + switch(W:colourName) + if("mime") + to_chat(usr,"This marker is too depressing to be contained in this box.") + return + if("rainbow") + to_chat(usr,"This marker is too childish to be contained in this box.") + return + ..() + //////////// //CIG PACK// //////////// @@ -253,15 +295,17 @@ reagents.trans_to_obj(C, (reagents.total_volume/contents.len)) ..() -/obj/item/weapon/storage/rollingpapers +/obj/item/weapon/storage/fancy/rollingpapers name = "rolling paper pack" desc = "A small cardboard pack containing several folded rolling papers." icon_state = "paperbox" icon = 'icons/obj/cigarettes.dmi' w_class = ITEMSIZE_TINY - throwforce = 1 + throwforce = 2 + slot_flags = SLOT_BELT storage_slots = 14 can_hold = list(/obj/item/weapon/rollingpaper) + icon_type = "paper" starts_with = list(/obj/item/weapon/rollingpaper = 14) /* diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 7b310ccaa70..b11151b01d9 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -195,11 +195,18 @@ var/instant = 0 var/colourName = "red" //for updateIcon purposes - suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] - viewers(user) << "[user] is jamming the [src.name] up [TU.his] nose and into [TU.his] brain. It looks like [TU.he] [TU.is] trying to commit suicide." - return (BRUTELOSS|OXYLOSS) +/obj/item/weapon/pen/crayon/suicide_act(mob/user) + var/datum/gender/TU = gender_datums[user.get_visible_gender()] + viewers(user) << "[user] is jamming the [src.name] up [TU.his] nose and into [TU.his] brain. It looks like [TU.he] [TU.is] trying to commit suicide." + return (BRUTELOSS|OXYLOSS) - New() - name = "[colourName] crayon" - ..() +/obj/item/weapon/pen/crayon/New() + name = "[colourName] crayon" + +/obj/item/weapon/pen/crayon/marker + name = "marker" + desc = "A chisel-tip permanent marker. Hopefully non-toxic." + icon_state = "markerred" + +/obj/item/weapon/pen/crayon/marker/New() + name = "[colourName] marker" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index 9b15c07b70d..6c83b0e26da 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -49,6 +49,60 @@ id = "crayon_dust_brown" color = "#846F35" +/datum/reagent/marker_ink + name = "Marker ink" + id = "marker_ink" + description = "Intensely coloured ink used in markers." + taste_description = "extremely bitter" + reagent_state = LIQUID + color = "#888888" + overdose = 5 + +/datum/reagent/marker_ink/black + name = "Black marker ink" + id = "marker_ink_black" + color = "#000000" + +/datum/reagent/marker_ink/red + name = "Red marker ink" + id = "marker_ink_red" + color = "#FE191A" + +/datum/reagent/marker_ink/orange + name = "Orange marker ink" + id = "marker_ink_orange" + color = "#FFBE4F" + +/datum/reagent/marker_ink/yellow + name = "Yellow marker ink" + id = "marker_ink_yellow" + color = "#FDFE7D" + +/datum/reagent/marker_ink/green + name = "Green marker ink" + id = "marker_ink_green" + color = "#18A31A" + +/datum/reagent/marker_ink/blue + name = "Blue marker ink" + id = "marker_ink_blue" + color = "#247CFF" + +/datum/reagent/marker_ink/purple + name = "Purple marker ink" + id = "marker_ink_purple" + color = "#CC0099" + +/datum/reagent/marker_ink/grey //Mime + name = "Grey marker ink" + id = "marker_ink_grey" + color = "#808080" + +/datum/reagent/marker_ink/brown //Rainbow + name = "Brown marker ink" + id = "marker_ink_brown" + color = "#846F35" + /datum/reagent/paint name = "Paint" id = "paint" diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 37634ac28a4..4539a70516c 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -868,7 +868,7 @@ name = "Red paint" id = "red_paint" result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_red" = 1) + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_red" = 1) result_amount = 5 /datum/chemical_reaction/red_paint/send_data() @@ -878,7 +878,7 @@ name = "Orange paint" id = "orange_paint" result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_orange" = 1) + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_orange" = 1) result_amount = 5 /datum/chemical_reaction/orange_paint/send_data() @@ -888,7 +888,7 @@ name = "Yellow paint" id = "yellow_paint" result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_yellow" = 1) + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_yellow" = 1) result_amount = 5 /datum/chemical_reaction/yellow_paint/send_data() @@ -898,7 +898,7 @@ name = "Green paint" id = "green_paint" result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_green" = 1) + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_green" = 1) result_amount = 5 /datum/chemical_reaction/green_paint/send_data() @@ -908,7 +908,7 @@ name = "Blue paint" id = "blue_paint" result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_blue" = 1) + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_blue" = 1) result_amount = 5 /datum/chemical_reaction/blue_paint/send_data() @@ -918,7 +918,7 @@ name = "Purple paint" id = "purple_paint" result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_purple" = 1) + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_purple" = 1) result_amount = 5 /datum/chemical_reaction/purple_paint/send_data() @@ -928,7 +928,7 @@ name = "Grey paint" id = "grey_paint" result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_grey" = 1) + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_grey" = 1) result_amount = 5 /datum/chemical_reaction/grey_paint/send_data() @@ -938,7 +938,7 @@ name = "Brown paint" id = "brown_paint" result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_brown" = 1) + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_brown" = 1) result_amount = 5 /datum/chemical_reaction/brown_paint/send_data() diff --git a/html/changelogs/Billybangles - Markers.yml b/html/changelogs/Billybangles - Markers.yml new file mode 100644 index 00000000000..afab2bf8cb3 --- /dev/null +++ b/html/changelogs/Billybangles - Markers.yml @@ -0,0 +1,38 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: battlefieldCommander + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added permanent markers, an alternative to crayons." + - tweak: "The chemistry recipe for paint now uses marker ink instead of crayon dust." + - rscdel: "Removed crayon boxes from the map. They can still be ordered from cargo in case you need a snack." diff --git a/icons/obj/crayons.dmi b/icons/obj/crayons.dmi index 7ebabd5a81ef5bdfce1a76163e72b1fc54133f4a..80ab2d153caad02fb602cb8954094f04991f2a46 100644 GIT binary patch literal 5079 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 Date: Mon, 19 Mar 2018 20:25:10 -0400 Subject: [PATCH 05/74] removes crayon boxes from map you can still order them from cargo though, for all those hungry marines out there. --- maps/northern_star/polaris-1.dmm | 4 ++-- maps/southern_cross/southern_cross-1.dmm | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/maps/northern_star/polaris-1.dmm b/maps/northern_star/polaris-1.dmm index 3f1213a0508..f09d64398e3 100644 --- a/maps/northern_star/polaris-1.dmm +++ b/maps/northern_star/polaris-1.dmm @@ -298,7 +298,7 @@ "afL" = (/turf/simulated/wall,/area/chapel/main) "afM" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp{pixel_y = 10},/obj/machinery/camera/network/civilian{c_tag = "CIV - Chapel Office"; dir = 4},/turf/simulated/floor/lino,/area/chapel/office) "afN" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen/blue{pixel_x = 5; pixel_y = 5},/turf/simulated/floor/lino,/area/chapel/office) -"afO" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/fancy/crayons,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/lino,/area/chapel/office) +"afO" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/weapon/storage/fancy/markers,/turf/simulated/floor/lino,/area/chapel/office) "afP" = (/turf/simulated/floor/lino,/area/chapel/office) "afQ" = (/obj/structure/closet/wardrobe/chaplain_black,/obj/machinery/light{dir = 4},/turf/simulated/floor/lino,/area/chapel/office) "afR" = (/obj/machinery/light/small{dir = 8},/obj/item/weapon/storage/bible,/obj/structure/table/rack,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/clean,/turf/simulated/floor,/area/maintenance/locker) @@ -1821,7 +1821,7 @@ "aJa" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/belt/utility,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/security,/obj/random/maintenance/security,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "aJb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/maintenance/security_starboard) "aJc" = (/turf/simulated/wall,/area/storage/art) -"aJd" = (/obj/structure/table/standard,/obj/item/weapon/storage/fancy/crayons,/obj/item/weapon/storage/fancy/crayons,/turf/simulated/floor/tiled,/area/storage/art) +"aJd" = (/obj/structure/table/standard,/obj/item/weapon/storage/fancy/markers,/obj/item/weapon/storage/fancy/markers,/turf/simulated/floor/tiled,/area/storage/art) "aJe" = (/obj/structure/table/standard,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/turf/simulated/floor/tiled,/area/storage/art) "aJf" = (/obj/structure/table/standard,/obj/item/weapon/hand_labeler,/obj/item/weapon/hand_labeler,/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/turf/simulated/floor/tiled,/area/storage/art) "aJg" = (/obj/structure/table/standard,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/atmospherics/unary/vent_pump/on,/obj/item/device/taperecorder,/obj/item/device/taperecorder,/turf/simulated/floor/tiled,/area/storage/art) diff --git a/maps/southern_cross/southern_cross-1.dmm b/maps/southern_cross/southern_cross-1.dmm index 54fe25d22ec..55517709358 100644 --- a/maps/southern_cross/southern_cross-1.dmm +++ b/maps/southern_cross/southern_cross-1.dmm @@ -3981,7 +3981,7 @@ "byC" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/purple/border{dir = 4},/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/turf/simulated/floor/tiled,/area/janitor) "byD" = (/obj/structure/closet/toolcloset,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/yellow/border{dir = 8},/turf/simulated/floor/tiled,/area/storage/auxillary) "byE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/table/steel,/obj/random/maintenance/engineering,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled,/area/storage/auxillary) -"byF" = (/obj/structure/table/steel,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen/blue{pixel_x = -5; pixel_y = -1},/obj/item/weapon/pen/red{pixel_x = -1; pixel_y = 3},/obj/item/weapon/storage/fancy/crayons,/obj/item/weapon/storage/fancy/crayons,/obj/machinery/camera/network/civilian{c_tag = "CIV - Auxiliary Storage"; dir = 8},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/yellow/border{dir = 4},/turf/simulated/floor/tiled,/area/storage/auxillary) +"byF" = (/obj/structure/table/steel,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen/blue{pixel_x = -5; pixel_y = -1},/obj/item/weapon/pen/red{pixel_x = -1; pixel_y = 3},/obj/machinery/camera/network/civilian{c_tag = "CIV - Auxiliary Storage"; dir = 8},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/yellow/border{dir = 4},/obj/item/weapon/storage/fancy/markers,/obj/item/weapon/storage/fancy/markers,/turf/simulated/floor/tiled,/area/storage/auxillary) "byG" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 4},/obj/machinery/meter,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/research) "byH" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Firefighting Equipment"; req_access = null; req_one_access = list(12,47)},/turf/simulated/floor/plating,/area/maintenance/research) "byI" = (/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor/plating,/area/maintenance/research) @@ -8505,7 +8505,7 @@ "dhC" = (/obj/machinery/photocopier,/turf/simulated/floor/lino,/area/chapel/office) "dhD" = (/obj/structure/table/wooden_reinforced,/obj/structure/flora/pottedplant/thinbush{pixel_y = 10},/turf/simulated/floor/lino,/area/chapel/office) "dhE" = (/obj/structure/table/wooden_reinforced,/obj/item/weapon/nullrod,/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater,/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/button/windowtint{id = "chapel"; pixel_x = -11; pixel_y = 24},/obj/machinery/light_switch{pixel_x = 11; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/lino,/area/chapel/office) -"dhF" = (/obj/structure/table/wooden_reinforced,/obj/item/weapon/storage/fancy/crayons,/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/turf/simulated/floor/lino,/area/chapel/office) +"dhF" = (/obj/structure/table/wooden_reinforced,/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/obj/item/weapon/storage/fancy/markers,/turf/simulated/floor/lino,/area/chapel/office) "dhG" = (/obj/structure/closet/wardrobe/chaplain_black,/turf/simulated/floor/lino,/area/chapel/office) "dhH" = (/obj/machinery/power/breakerbox/activated{RCon_tag = "Civilian Substation Bypass"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian) "dhI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/turf/simulated/floor/plating,/area/maintenance/substation/civilian) From d953a58413e767fbfbb3a15861b58b807aeb3243 Mon Sep 17 00:00:00 2001 From: Billy Bangles Date: Mon, 19 Mar 2018 21:23:48 -0400 Subject: [PATCH 06/74] travis pls why must we argue so --- code/game/objects/items/weapons/storage/fancy.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index fc34e0999d2..762720e390c 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -295,7 +295,7 @@ reagents.trans_to_obj(C, (reagents.total_volume/contents.len)) ..() -/obj/item/weapon/storage/fancy/rollingpapers +/obj/item/weapon/storage/rollingpapers name = "rolling paper pack" desc = "A small cardboard pack containing several folded rolling papers." icon_state = "paperbox" @@ -305,7 +305,6 @@ slot_flags = SLOT_BELT storage_slots = 14 can_hold = list(/obj/item/weapon/rollingpaper) - icon_type = "paper" starts_with = list(/obj/item/weapon/rollingpaper = 14) /* From 9d60c99dac87faca0f62b926e70357682cbc5ebd Mon Sep 17 00:00:00 2001 From: Screemonster Date: Tue, 20 Mar 2018 15:08:08 +0000 Subject: [PATCH 07/74] Clean up diona-specific stuff in life() --- code/modules/mob/living/carbon/human/life.dm | 30 ------------------- .../carbon/human/species/station/station.dm | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index b27f98bc40c..b5aef7ac1fa 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -850,28 +850,6 @@ if(status_flags & GODMODE) return 0 //godmode - var/obj/item/organ/internal/diona/node/light_organ = locate() in internal_organs - - if(!isSynthetic()) - if(light_organ && !light_organ.is_broken()) - var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing - if(isturf(loc)) //else, there's considered to be no light - var/turf/T = loc - light_amount = T.get_lumcount() * 10 - nutrition += light_amount - traumatic_shock -= light_amount - - if(species.flags & IS_PLANT) - if(nutrition > 450) - nutrition = 450 - - if(light_amount >= 3) //if there's enough light, heal - adjustBruteLoss(-(round(light_amount/2))) - adjustFireLoss(-(round(light_amount/2))) - adjustToxLoss(-(light_amount)) - adjustOxyLoss(-(light_amount)) - //TODO: heal wounds, heal broken limbs. - if(species.light_dam) var/light_amount = 0 if(isturf(loc)) @@ -899,14 +877,6 @@ if(overeatduration > 1) overeatduration -= 2 //doubled the unfat rate - if(!isSynthetic() && (species.flags & IS_PLANT) && (!light_organ || light_organ.is_broken())) - if(nutrition < 200) - take_overall_damage(2,0) - - //traumatic_shock is updated every tick, incrementing that is pointless - shock_stage is the counter. - //Not that it matters much for diona, who have NO_PAIN. - shock_stage++ - // TODO: stomach and bloodstream organ. if(!isSynthetic()) handle_trace_chems() 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 231db8a9fb0..f1911b29df5 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -405,3 +405,33 @@ qdel(D) H.visible_message("\The [H] splits apart with a wet slithering noise!") + +/datum/species/diona/handle_environment_special(var/mob/living/carbon/human/H) + if(H.inStasisNow()) + return + + var/obj/item/organ/internal/diona/node/light_organ = locate() in H.internal_organs + + if(light_organ && !light_organ.is_broken()) + var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing + if(isturf(H.loc)) //else, there's considered to be no light + var/turf/T = H.loc + light_amount = T.get_lumcount() * 10 + H.nutrition += light_amount + H.shock_stage -= light_amount + + if(H.nutrition > 450) + H.nutrition = 450 + if(light_amount >= 3) //if there's enough light, heal + H.adjustBruteLoss(-(round(light_amount/2))) + H.adjustFireLoss(-(round(light_amount/2))) + H.adjustToxLoss(-(light_amount)) + H.adjustOxyLoss(-(light_amount)) + //TODO: heal wounds, heal broken limbs. + + else if(H.nutrition < 200) + H.take_overall_damage(2,0) + + //traumatic_shock is updated every tick, incrementing that is pointless - shock_stage is the counter. + //Not that it matters much for diona, who have NO_PAIN. + H.shock_stage++ From 6e9554baa2269e6334eb3f01e562ffec5d150df2 Mon Sep 17 00:00:00 2001 From: Abbie Fland <34605836+AbbieFland@users.noreply.github.com> Date: Wed, 21 Mar 2018 00:56:02 +0000 Subject: [PATCH 08/74] Fixes preview color splotch blues Due to what looks like a copy-paste error, previously it didn't pad the blue hex value. This meant blue values of 1-15 would display as e.g. "f0" instead of "0f" and looked nothing like the actual color. Previously a dark grey of 15,15,15 would get a preview splotch of bright blue; this fix makes the splotch display as the same dark grey used ingame. --- .../modules/client/preference_setup/general/03_body.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 432dfdbb6ea..ea8f029b88b 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -282,21 +282,21 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O . += "Hair
" if(has_flag(mob_species, HAS_HAIR_COLOR)) - . += "Change Color
__
" + . += "Change Color
__
" . += " Style: [pref.h_style]
" . += "
Facial
" if(has_flag(mob_species, HAS_HAIR_COLOR)) - . += "Change Color
__
" + . += "Change Color
__
" . += " Style: [pref.f_style]
" if(has_flag(mob_species, HAS_EYE_COLOR)) . += "
Eyes
" - . += "Change Color
__

" + . += "Change Color
__

" if(has_flag(mob_species, HAS_SKIN_COLOR)) . += "
Body Color
" - . += "Change Color
__

" + . += "Change Color
__

" . += "
Body Markings +
" for(var/M in pref.body_markings) @@ -307,7 +307,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O . += "
" . += "Allow Synth color: [pref.synth_color ? "Yes" : "No"]
" if(pref.synth_color) - . += "Change Color
__
" + . += "Change Color
__
" . = jointext(.,null) From de6da4a86c7c40cbfc641fe01ecc4753a4d8b571 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 12 Mar 2018 18:25:53 -0400 Subject: [PATCH 09/74] POLARIS: Tooltip framework, and mob tooltips --- code/_helpers/mobs.dm | 13 + code/game/atoms.dm | 6 + code/modules/client/client defines.dm | 1 + .../client/preference_setup/global/01_ui.dm | 10 + .../preference_setup/global/setting_datums.dm | 6 + code/modules/client/preferences.dm | 1 + .../client/preferences_toggle_procs.dm | 13 + code/modules/client/ui_style.dm | 9 + code/modules/mob/living/carbon/human/human.dm | 50 ++++ .../mob/living/simple_animal/animals/bat.dm | 1 + .../mob/living/simple_animal/animals/bear.dm | 1 + .../mob/living/simple_animal/animals/carp.dm | 1 + .../mob/living/simple_animal/animals/cat.dm | 1 + .../mob/living/simple_animal/animals/corgi.dm | 2 + .../mob/living/simple_animal/animals/crab.dm | 1 + .../simple_animal/animals/farm_animals.dm | 4 + .../simple_animal/animals/giant_spider.dm | 1 + .../mob/living/simple_animal/animals/goose.dm | 1 + .../living/simple_animal/animals/lizard.dm | 1 + .../mob/living/simple_animal/animals/mouse.dm | 1 + .../living/simple_animal/animals/parrot.dm | 1 + .../living/simple_animal/animals/penguin.dm | 1 + .../mob/living/simple_animal/animals/slime.dm | 1 + .../living/simple_animal/animals/spiderbot.dm | 1 + .../mob/living/simple_animal/simple_animal.dm | 6 + code/modules/mob/login.dm | 4 + code/modules/mob/mob.dm | 11 + code/modules/tooltip/tooltip.dm | 124 +++++++++ code/modules/tooltip/tooltip.html | 249 ++++++++++++++++++ interface/skin.dmf | 8 + polaris.dme | 1 + 31 files changed, 531 insertions(+) create mode 100644 code/modules/tooltip/tooltip.dm create mode 100644 code/modules/tooltip/tooltip.html diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index a1b58d06f86..e82e618651d 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -276,3 +276,16 @@ Proc for attack log creation, because really why not humans += H return humans + +/proc/getviewsize(view) + var/viewX + var/viewY + if(isnum(view)) + var/totalviewrange = 1 + 2 * view + viewX = totalviewrange + viewY = totalviewrange + else + var/list/viewrangelist = splittext(view,"x") + viewX = text2num(viewrangelist[1]) + viewY = text2num(viewrangelist[2]) + return list(viewX, viewY) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index c994aff121d..c396a54839f 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -511,3 +511,9 @@ /atom/proc/AllowDrop() return FALSE + +/atom/proc/make_nametag_name(mob/user) + return name + +/atom/proc/make_nametag_desc(mob/user) + return "" //Desc itself is often too long to use diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index e4c5a10d356..09d4738d67b 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -22,6 +22,7 @@ var/adminobs = null var/area = null var/time_died_as_mouse = null //when the client last died as a mouse + var/datum/tooltip/tooltips = null var/adminhelped = 0 diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index 09289c1068f..6168aa36b07 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -7,24 +7,28 @@ S["UI_style_color"] >> pref.UI_style_color S["UI_style_alpha"] >> pref.UI_style_alpha S["ooccolor"] >> pref.ooccolor + S["tooltipstyle"] >> pref.tooltipstyle /datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S) S["UI_style"] << pref.UI_style S["UI_style_color"] << pref.UI_style_color S["UI_style_alpha"] << pref.UI_style_alpha S["ooccolor"] << pref.ooccolor + S["tooltipstyle"] >> pref.tooltipstyle /datum/category_item/player_setup_item/player_global/ui/sanitize_preferences() pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style)) pref.UI_style_color = sanitize_hexcolor(pref.UI_style_color, initial(pref.UI_style_color)) pref.UI_style_alpha = sanitize_integer(pref.UI_style_alpha, 0, 255, initial(pref.UI_style_alpha)) pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor)) + pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, all_tooltip_styles[1]) /datum/category_item/player_setup_item/player_global/ui/content(var/mob/user) . = "UI Style: [pref.UI_style]
" . += "Custom UI (recommended for White UI):
" . += "-Color: [pref.UI_style_color]
__
reset
" . += "-Alpha(transparency): [pref.UI_style_alpha]reset
" + . += "Tooltip Style: [pref.tooltipstyle]
" if(can_select_ooc_color(user)) . += "OOC Color:" if(pref.ooccolor == initial(pref.ooccolor)) @@ -57,6 +61,12 @@ pref.ooccolor = new_ooccolor return TOPIC_REFRESH + else if(href_list["select_tooltip_style"]) + var/tooltip_style_new = input(user, "Choose tooltip style.", "Character Preference", pref.tooltipstyle) as null|anything in all_tooltip_styles + if(!tooltip_style_new || !CanUseTopic(user)) return TOPIC_NOACTION + pref.tooltipstyle = tooltip_style_new + return TOPIC_REFRESH + else if(href_list["reset"]) switch(href_list["reset"]) if("ui") diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm index a85befce774..5d61603d8d9 100644 --- a/code/modules/client/preference_setup/global/setting_datums.dm +++ b/code/modules/client/preference_setup/global/setting_datums.dm @@ -98,6 +98,12 @@ var/list/_client_preferences_by_type enabled_description = "Show" disabled_description = "Hide" +/datum/client_preference/mob_tooltips + description ="Mob tooltips" + key = "MOB_TOOLTIPS" + enabled_description = "Show" + disabled_description = "Hide" + /datum/client_preference/attack_icons description ="Attack icons" key = "ATTACK_ICONS" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 3c5e1f4a61b..546c0594cf7 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -21,6 +21,7 @@ datum/preferences var/UI_style = "Midnight" var/UI_style_color = "#ffffff" var/UI_style_alpha = 255 + var/tooltipstyle = "Midnight" //Style for popup tooltips //character preferences var/real_name //our character's name diff --git a/code/modules/client/preferences_toggle_procs.dm b/code/modules/client/preferences_toggle_procs.dm index bcd4e3a0c1a..3b751800c9e 100644 --- a/code/modules/client/preferences_toggle_procs.dm +++ b/code/modules/client/preferences_toggle_procs.dm @@ -192,6 +192,19 @@ feedback_add_details("admin_verb","TFiringMode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/verb/toggle_mob_tooltips() + set name = "Toggle Mob Tooltips" + set category = "Preferences" + set desc = "Toggles displaying name/species over mobs when moused over." + + var/pref_path = /datum/client_preference/mob_tooltips + toggle_preference(pref_path) + prefs.save_preferences() + + src << "You will now [(is_preference_enabled(/datum/client_preference/mob_tooltips)) ? "see" : "not see"] mob tooltips." + + feedback_add_details("admin_verb","TMobTooltips") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + //Toggles for Staff //Developers diff --git a/code/modules/client/ui_style.dm b/code/modules/client/ui_style.dm index d8d683d5d3c..4a736aec5ec 100644 --- a/code/modules/client/ui_style.dm +++ b/code/modules/client/ui_style.dm @@ -20,6 +20,15 @@ "Hologram" = 'icons/mob/screen1_robot_minimalist.dmi' ) +var/global/list/all_tooltip_styles = list( + "Midnight", //Default for everyone is the first one, + "Plasmafire", + "Retro", + "Slimecore", + "Operative", + "Clockwork" + ) + /proc/ui_style2icon(ui_style) if(ui_style in all_ui_styles) return all_ui_styles[ui_style] diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 09f6c62276f..2793f11d87b 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1562,3 +1562,53 @@ status_flags &= ~HIDING //No hiding for you. Mob layer should be updated naturally, but it actually isn't. else layer = HIDING_LAYER + +/mob/living/carbon/human/proc/get_display_species() + //Shows species in tooltip + //Beepboops get special text if obviously beepboop + if(looksSynthetic()) + if(gender == MALE) + return "Android" + else if(gender == FEMALE) + return "Gynoid" + else + return "Synthetic" + //Else species name + if(species) + return species.get_examine_name() + //Else CRITICAL FAILURE! + return "" + +/mob/living/carbon/human/make_nametag_name(mob/user) + return name //Could do fancy stuff here? + +/mob/living/carbon/human/make_nametag_desc(mob/user) + var/msg = "" + if(hasHUD(user,"security")) + //Try to find their name + var/perpname + if(wear_id) + var/obj/item/weapon/card/id/I = wear_id.GetID() + if(I) + perpname = I.registered_name + else + perpname = name + else + perpname = name + //Try to find their record + var/criminal = "None" + if(perpname) + var/datum/data/record/G = find_general_record("name", perpname) + if(G) + var/datum/data/record/S = find_security_record("id", G.fields["id"]) + if(S) + criminal = S.fields["criminal"] + //If it's interesting, append + if(criminal != "None") + msg += "([criminal]) " + + if(hasHUD(user,"medical")) + msg += "(Health: [round((health/getMaxHealth())*100)]%) " + + msg += get_display_species() + return msg diff --git a/code/modules/mob/living/simple_animal/animals/bat.dm b/code/modules/mob/living/simple_animal/animals/bat.dm index edd9c3dec52..1be28a078f6 100644 --- a/code/modules/mob/living/simple_animal/animals/bat.dm +++ b/code/modules/mob/living/simple_animal/animals/bat.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/hostile/scarybat name = "space bats" desc = "A swarm of cute little blood sucking bats that looks pretty upset." + tt_desc = "Desmodus rotundus" //Common vampire bat icon = 'icons/mob/bats.dmi' icon_state = "bat" icon_living = "bat" diff --git a/code/modules/mob/living/simple_animal/animals/bear.dm b/code/modules/mob/living/simple_animal/animals/bear.dm index 0680714f863..d0f871e7cee 100644 --- a/code/modules/mob/living/simple_animal/animals/bear.dm +++ b/code/modules/mob/living/simple_animal/animals/bear.dm @@ -2,6 +2,7 @@ /mob/living/simple_animal/hostile/bear name = "space bear" desc = "RawrRawr!!" + tt_desc = "Ursinae aetherius" //...bearspace? Maybe. icon_state = "bear" icon_living = "bear" icon_dead = "bear_dead" diff --git a/code/modules/mob/living/simple_animal/animals/carp.dm b/code/modules/mob/living/simple_animal/animals/carp.dm index 4dc4daffdaf..8b6e01c4528 100644 --- a/code/modules/mob/living/simple_animal/animals/carp.dm +++ b/code/modules/mob/living/simple_animal/animals/carp.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/hostile/carp name = "space carp" desc = "A ferocious, fang-bearing creature that resembles a fish." + tt_desc = "Cyprinus aetherius" //carpspace? maybe icon_state = "carp" icon_living = "carp" icon_dead = "carp_dead" diff --git a/code/modules/mob/living/simple_animal/animals/cat.dm b/code/modules/mob/living/simple_animal/animals/cat.dm index 81cd043ce0b..74121bdd53e 100644 --- a/code/modules/mob/living/simple_animal/animals/cat.dm +++ b/code/modules/mob/living/simple_animal/animals/cat.dm @@ -2,6 +2,7 @@ /mob/living/simple_animal/cat name = "cat" desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers." + tt_desc = "Felis catus" intelligence_level = SA_ANIMAL icon_state = "cat2" item_state = "cat2" diff --git a/code/modules/mob/living/simple_animal/animals/corgi.dm b/code/modules/mob/living/simple_animal/animals/corgi.dm index a6d0dcd9c0c..d5c198ad781 100644 --- a/code/modules/mob/living/simple_animal/animals/corgi.dm +++ b/code/modules/mob/living/simple_animal/animals/corgi.dm @@ -3,6 +3,7 @@ name = "corgi" real_name = "corgi" desc = "It's a corgi." + tt_desc = "Canis familiaris" intelligence_level = SA_ANIMAL icon_state = "corgi" icon_living = "corgi" @@ -37,6 +38,7 @@ real_name = "Ian" //Intended to hold the name without altering it. gender = MALE desc = "It's a corgi." + tt_desc = "Canis commandus" var/turns_since_scan = 0 var/obj/movement_target response_help = "pets" diff --git a/code/modules/mob/living/simple_animal/animals/crab.dm b/code/modules/mob/living/simple_animal/animals/crab.dm index 04b6161d3bb..68aa2afd148 100644 --- a/code/modules/mob/living/simple_animal/animals/crab.dm +++ b/code/modules/mob/living/simple_animal/animals/crab.dm @@ -2,6 +2,7 @@ /mob/living/simple_animal/crab name = "crab" desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time." + tt_desc = "Ranina ranina" icon_state = "crab" icon_living = "crab" icon_dead = "crab_dead" diff --git a/code/modules/mob/living/simple_animal/animals/farm_animals.dm b/code/modules/mob/living/simple_animal/animals/farm_animals.dm index 213aff73bfc..52904786a4a 100644 --- a/code/modules/mob/living/simple_animal/animals/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/animals/farm_animals.dm @@ -2,6 +2,7 @@ /mob/living/simple_animal/retaliate/goat name = "goat" desc = "Not known for their pleasant disposition." + tt_desc = "Oreamnos americanus" icon_state = "goat" icon_living = "goat" icon_dead = "goat_dead" @@ -85,6 +86,7 @@ /mob/living/simple_animal/cow name = "cow" desc = "Known for their milk, just don't tip them over." + tt_desc = "Bos taurus" icon_state = "cow" icon_living = "cow" icon_dead = "cow_dead" @@ -153,6 +155,7 @@ /mob/living/simple_animal/chick name = "\improper chick" desc = "Adorable! They make such a racket though." + tt_desc = "Gallus domesticus" icon_state = "chick" icon_living = "chick" icon_dead = "chick_dead" @@ -203,6 +206,7 @@ var/global/chicken_count = 0 /mob/living/simple_animal/chicken name = "\improper chicken" desc = "Hopefully the eggs are good this season." + tt_desc = "Gallus domesticus" icon_state = "chicken" icon_living = "chicken" icon_dead = "chicken_dead" diff --git a/code/modules/mob/living/simple_animal/animals/giant_spider.dm b/code/modules/mob/living/simple_animal/animals/giant_spider.dm index 4eca650adee..439e401e089 100644 --- a/code/modules/mob/living/simple_animal/animals/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/animals/giant_spider.dm @@ -8,6 +8,7 @@ /mob/living/simple_animal/hostile/giant_spider name = "giant spider" desc = "Furry and brown, it makes you shudder to look at it. This one has deep red eyes." + tt_desc = "Atrax robustus gigantus" icon_state = "guard" icon_living = "guard" icon_dead = "guard_dead" diff --git a/code/modules/mob/living/simple_animal/animals/goose.dm b/code/modules/mob/living/simple_animal/animals/goose.dm index dd3b93c4795..764a07415cd 100644 --- a/code/modules/mob/living/simple_animal/animals/goose.dm +++ b/code/modules/mob/living/simple_animal/animals/goose.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/hostile/goose name = "space goose" desc = "That's no duck. That's a space goose. You have a bad feeling about this." + tt_desc = "Anser aetherius" //Goose space?! icon_state = "goose" icon_living = "goose" icon_dead = "goose_dead" diff --git a/code/modules/mob/living/simple_animal/animals/lizard.dm b/code/modules/mob/living/simple_animal/animals/lizard.dm index 38822faf0df..c4c1487315d 100644 --- a/code/modules/mob/living/simple_animal/animals/lizard.dm +++ b/code/modules/mob/living/simple_animal/animals/lizard.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/lizard name = "Lizard" desc = "A cute tiny lizard." + tt_desc = "Gekko gecko" icon = 'icons/mob/critter.dmi' icon_state = "lizard" icon_living = "lizard" diff --git a/code/modules/mob/living/simple_animal/animals/mouse.dm b/code/modules/mob/living/simple_animal/animals/mouse.dm index 87df9015277..123e82a6110 100644 --- a/code/modules/mob/living/simple_animal/animals/mouse.dm +++ b/code/modules/mob/living/simple_animal/animals/mouse.dm @@ -2,6 +2,7 @@ name = "mouse" real_name = "mouse" desc = "It's a small rodent." + tt_desc = "Mus musculus" icon_state = "mouse_gray" item_state = "mouse_gray" icon_living = "mouse_gray" diff --git a/code/modules/mob/living/simple_animal/animals/parrot.dm b/code/modules/mob/living/simple_animal/animals/parrot.dm index 59e04cf1d6b..67d1a1071c8 100644 --- a/code/modules/mob/living/simple_animal/animals/parrot.dm +++ b/code/modules/mob/living/simple_animal/animals/parrot.dm @@ -31,6 +31,7 @@ /mob/living/simple_animal/parrot name = "parrot" desc = "The parrot squawks, \"It's a parrot! BAWWK!\"" + tt_desc = "Poicephalus robustus" icon = 'icons/mob/animal.dmi' icon_state = "parrot_fly" icon_living = "parrot_fly" diff --git a/code/modules/mob/living/simple_animal/animals/penguin.dm b/code/modules/mob/living/simple_animal/animals/penguin.dm index 4bb985d1acb..8463d9ac39c 100644 --- a/code/modules/mob/living/simple_animal/animals/penguin.dm +++ b/code/modules/mob/living/simple_animal/animals/penguin.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/penguin name = "space penguin" desc = "An ungainly, waddling, cute, and VERY well-dressed bird." + tt_desc = "Aptenodytes forsteri" icon_state = "penguin" icon_living = "penguin" icon_dead = "penguin_dead" diff --git a/code/modules/mob/living/simple_animal/animals/slime.dm b/code/modules/mob/living/simple_animal/animals/slime.dm index f7d23771a3c..fdb4347ae92 100644 --- a/code/modules/mob/living/simple_animal/animals/slime.dm +++ b/code/modules/mob/living/simple_animal/animals/slime.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/slime name = "pet slime" desc = "A lovable, domesticated slime." + tt_desc = "Amorphidae proteus" icon = 'icons/mob/slimes.dmi' icon_state = "grey baby slime" icon_living = "grey baby slime" diff --git a/code/modules/mob/living/simple_animal/animals/spiderbot.dm b/code/modules/mob/living/simple_animal/animals/spiderbot.dm index 7ae8edfb7a3..83f18c071a7 100644 --- a/code/modules/mob/living/simple_animal/animals/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/animals/spiderbot.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/spiderbot name = "spider-bot" desc = "A skittering robotic friend!" + tt_desc = "Maintenance Robot" icon = 'icons/mob/robots.dmi' icon_state = "spiderbot-chassis" icon_living = "spiderbot-chassis" diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 885b2015bbf..631954fbedb 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -5,6 +5,7 @@ /mob/living/simple_animal name = "animal" + desc = "" icon = 'icons/mob/animal.dmi' health = 20 maxHealth = 20 @@ -13,6 +14,8 @@ mob_swap_flags = MONKEY|SLIME|HUMAN mob_push_flags = MONKEY|SLIME|HUMAN + var/tt_desc = "Uncataloged Life Form" //Tooltip description + //Settings for played mobs var/show_stat_health = 1 // Does the percentage health show in the stat panel for the mob var/ai_inactive = 0 // Set to 1 to turn off most AI actions @@ -1697,3 +1700,6 @@ /mob/living/simple_animal/retaliate retaliate = 1 destroy_surroundings = 1 + +/mob/living/simple_animal/make_nametag_desc(mob/user) + return "tt_desc" diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index f29a396af68..0c6b5a5d7ce 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -57,3 +57,7 @@ //set macro to normal incase it was overriden (like cyborg currently does) client.set_hotkeys_macro("macro", "hotkeymode") + + if(!client.tooltips) + client.tooltips = new(client) + \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 00864d0a04d..4ed88ef2cbd 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1143,3 +1143,14 @@ mob/proc/yank_out_object() //Throwing stuff /mob/proc/throw_item(atom/target) return + +/mob/MouseEntered(location, control, params) + if(usr != src && usr.is_preference_enabled(/datum/client_preference/mob_tooltips)) + openToolTip(user = usr, tip_src = src, params = params, title = make_nametag_name(usr), content = make_nametag_desc(usr)) + + ..() + +/mob/MouseExited() + closeToolTip(usr) //No reason not to, really + + ..() diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm new file mode 100644 index 00000000000..1b03157e83e --- /dev/null +++ b/code/modules/tooltip/tooltip.dm @@ -0,0 +1,124 @@ +/* +Tooltips v1.1 - 22/10/15 +Developed by Wire (#goonstation on irc.synirc.net) +- Added support for screen_loc pixel offsets. Should work. Maybe. +- Added init function to more efficiently send base vars + +Configuration: +- Set control to the correct skin element (remember to actually place the skin element) +- Set file to the correct path for the .html file (remember to actually place the html file) +- Attach the datum to the user client on login, e.g. +/client/New() + src.tooltips = new /datum/tooltip(src) + +Usage: +- Define mouse event procs on your (probably HUD) object and simply call the show and hide procs respectively: +/obj/screen/hud + MouseEntered(location, control, params) + usr.client.tooltip.show(params, title = src.name, content = src.desc) + + MouseExited() + usr.client.tooltip.hide() + +Customization: +- Theming can be done by passing the theme var to show() and using css in the html file to change the look +- For your convenience some pre-made themes are included + +Notes: +- You may have noticed 90% of the work is done via javascript on the client. Gotta save those cycles man. +- This is entirely untested in any other codebase besides goonstation so I have no idea if it will port nicely. Good luck! + - After testing and discussion (Wire, Remie, MrPerson, AnturK) ToolTips are ok and work for /tg/station13 +*/ + + +/datum/tooltip + var/client/owner + var/control = "mainwindow.tooltip" + var/showing = 0 + var/queueHide = 0 + var/init = 0 + + +/datum/tooltip/New(client/C) + if (C) + owner = C + owner << browse(file2text('code/modules/tooltip/tooltip.html'), "window=[control]") + ..() + + +/datum/tooltip/proc/show(atom/movable/thing, params = null, title = null, content = null, theme = "default", special = "none") + if (!thing || !params || (!title && !content) || !owner || !isnum(world.icon_size)) + return 0 + if (!init) + //Initialize some vars + init = 1 + owner << output(list2params(list(world.icon_size, control)), "[control]:tooltip.init") + + showing = 1 + + if (title && content) + title = "

[title]

" + content = "

[content]

" + else if (title && !content) + title = "

[title]

" + else if (!title && content) + content = "

[content]

" + + // Strip macros from item names + title = replacetext(title, "\proper", "") + title = replacetext(title, "\improper", "") + + //Make our dumb param object + if(params[1] != "i") //Byond Bug: http://www.byond.com/forum/?post=2352648 + params = "icon-x=16;icon-y=16;[params]" //Put in some placeholders + params = {"{ "cursor": "[params]", "screenLoc": "[thing.screen_loc]" }"} + + //Send stuff to the tooltip + var/view_size = getviewsize(owner.view) + owner << output(list2params(list(params, view_size[1] , view_size[2], "[title][content]", theme, special)), "[control]:tooltip.update") + + //If a hide() was hit while we were showing, run hide() again to avoid stuck tooltips + showing = 0 + if (queueHide) + hide() + + return 1 + + +/datum/tooltip/proc/hide() + if (queueHide) + schedule_task_with_source_in(1, src, .proc/do_hide) + else + do_hide() + + queueHide = showing ? TRUE : FALSE + + return TRUE + +/datum/tooltip/proc/do_hide() + winshow(owner, control, FALSE) + +/* TG SPECIFIC CODE */ + + +//Open a tooltip for user, at a location based on params +//Theme is a CSS class in tooltip.html, by default this wrapper chooses a CSS class based on the user's UI_style (Midnight, Plasmafire, Retro, etc) +//Includes sanity.checks +/proc/openToolTip(mob/user = null, atom/movable/tip_src = null, params = null, title = "", content = "", theme = "") + if(istype(user)) + if(user.client && user.client.tooltips) + if(!theme && user.client.prefs && user.client.prefs.tooltipstyle) + theme = lowertext(user.client.prefs.tooltipstyle) + if(!theme) + theme = "midnight" + user.client.tooltips.show(tip_src, params, title, content, theme) + + +//Arbitrarily close a user's tooltip +//Includes sanity checks. +/proc/closeToolTip(mob/user) + if(istype(user)) + if(user.client && user.client.tooltips) + user.client.tooltips.hide() + + diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html new file mode 100644 index 00000000000..67fb8a77f10 --- /dev/null +++ b/code/modules/tooltip/tooltip.html @@ -0,0 +1,249 @@ + + + + Tooltip + + + + + +
+
+
+ + + + diff --git a/interface/skin.dmf b/interface/skin.dmf index f32c3024961..571152d5c28 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -1936,6 +1936,14 @@ window "mainwindow" is-checked = false group = "" button-type = pushbox + elem "tooltip" + type = BROWSER + pos = 0,0 + size = 999x999 + anchor1 = none + anchor2 = none + is-visible = false + saved-params = "" window "mapwindow" elem "mapwindow" diff --git a/polaris.dme b/polaris.dme index 0bb899cea27..189c3665ec6 100644 --- a/polaris.dme +++ b/polaris.dme @@ -2313,6 +2313,7 @@ #include "code\modules\tables\tables.dm" #include "code\modules\tables\update_triggers.dm" #include "code\modules\tension\tension.dm" +#include "code\modules\tooltip\tooltip.dm" #include "code\modules\turbolift\_turbolift.dm" #include "code\modules\turbolift\turbolift.dm" #include "code\modules\turbolift\turbolift_areas.dm" From 0da7f7364113a8e4fe5decbba4376567751fa4e7 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 12 Mar 2018 20:25:36 -0400 Subject: [PATCH 10/74] POLARIS: Rename make_nametag_name/desc --- code/game/atoms.dm | 4 ++-- code/modules/mob/living/carbon/human/human.dm | 4 ++-- code/modules/mob/living/simple_animal/simple_animal.dm | 2 +- code/modules/mob/mob.dm | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index c396a54839f..e18970802e4 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -512,8 +512,8 @@ /atom/proc/AllowDrop() return FALSE -/atom/proc/make_nametag_name(mob/user) +/atom/proc/get_nametag_name(mob/user) return name -/atom/proc/make_nametag_desc(mob/user) +/atom/proc/get_nametag_desc(mob/user) return "" //Desc itself is often too long to use diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 2793f11d87b..2b4359f42d3 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1579,10 +1579,10 @@ //Else CRITICAL FAILURE! return "" -/mob/living/carbon/human/make_nametag_name(mob/user) +/mob/living/carbon/human/get_nametag_name(mob/user) return name //Could do fancy stuff here? -/mob/living/carbon/human/make_nametag_desc(mob/user) +/mob/living/carbon/human/get_nametag_desc(mob/user) var/msg = "" if(hasHUD(user,"security")) //Try to find their name diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 631954fbedb..a9245ce96a4 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -1701,5 +1701,5 @@ retaliate = 1 destroy_surroundings = 1 -/mob/living/simple_animal/make_nametag_desc(mob/user) +/mob/living/simple_animal/get_nametag_desc(mob/user) return "tt_desc" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4ed88ef2cbd..65ff381c9b2 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1146,7 +1146,7 @@ mob/proc/yank_out_object() /mob/MouseEntered(location, control, params) if(usr != src && usr.is_preference_enabled(/datum/client_preference/mob_tooltips)) - openToolTip(user = usr, tip_src = src, params = params, title = make_nametag_name(usr), content = make_nametag_desc(usr)) + openToolTip(user = usr, tip_src = src, params = params, title = get_nametag_name(usr), content = get_nametag_desc(usr)) ..() From 62f9cb0d47882a9ab13c94e69f0ca1e051e05bdd Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Fri, 16 Mar 2018 00:11:38 -0400 Subject: [PATCH 11/74] POLARIS: Fix tooltip style sanitize --- code/modules/client/preference_setup/global/01_ui.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index 6168aa36b07..29502ec9850 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -14,14 +14,14 @@ S["UI_style_color"] << pref.UI_style_color S["UI_style_alpha"] << pref.UI_style_alpha S["ooccolor"] << pref.ooccolor - S["tooltipstyle"] >> pref.tooltipstyle + S["tooltipstyle"] << pref.tooltipstyle /datum/category_item/player_setup_item/player_global/ui/sanitize_preferences() pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style)) pref.UI_style_color = sanitize_hexcolor(pref.UI_style_color, initial(pref.UI_style_color)) pref.UI_style_alpha = sanitize_integer(pref.UI_style_alpha, 0, 255, initial(pref.UI_style_alpha)) pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor)) - pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, all_tooltip_styles[1]) + pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, initial(pref.tooltipstyle)) /datum/category_item/player_setup_item/player_global/ui/content(var/mob/user) . = "UI Style: [pref.UI_style]
" From 77de03a356f164012c798be98ad110a414404738 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Fri, 16 Mar 2018 00:12:41 -0400 Subject: [PATCH 12/74] POLARIS: Fix simple animal tooltip --- code/modules/mob/living/simple_animal/simple_animal.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index a9245ce96a4..be3909d6619 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -1702,4 +1702,4 @@ destroy_surroundings = 1 /mob/living/simple_animal/get_nametag_desc(mob/user) - return "tt_desc" + return "[tt_desc]" From dfd07209b69fc7900ff34768cd262bcfcee7cf76 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sun, 18 Mar 2018 00:19:36 -0400 Subject: [PATCH 13/74] POLARIS: MouseDown closes tooltips too --- code/modules/mob/mob.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 65ff381c9b2..c418c287d88 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1150,6 +1150,11 @@ mob/proc/yank_out_object() ..() +/mob/MouseDown() + closeToolTip(usr) //No reason not to, really + + ..() + /mob/MouseExited() closeToolTip(usr) //No reason not to, really From 1bc490630d9080c44bbe6675e6d1ca5a84d5fb8d Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Wed, 31 Jan 2018 20:56:57 -0500 Subject: [PATCH 14/74] POLARIS: Fix two mistakes with the shuttle_arrival procs --- code/modules/shuttles/shuttle.dm | 2 +- code/modules/shuttles/shuttles_web.dm | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index 618ec3ff05a..8f8de00fc49 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -90,7 +90,7 @@ make_sounds(origin, HYPERSPACE_END) return //someone cancelled the launch - on_shuttle_departure() + on_shuttle_departure(origin) moving_status = SHUTTLE_INTRANSIT //shouldn't matter but just to be safe move(origin, destination) diff --git a/code/modules/shuttles/shuttles_web.dm b/code/modules/shuttles/shuttles_web.dm index a8ca493470d..d16956acdd0 100644 --- a/code/modules/shuttles/shuttles_web.dm +++ b/code/modules/shuttles/shuttles_web.dm @@ -43,9 +43,11 @@ last_move = world.time /datum/shuttle/web_shuttle/on_shuttle_departure() + ..() web_master.on_shuttle_departure() /datum/shuttle/web_shuttle/on_shuttle_arrival() + ..() web_master.on_shuttle_arrival() /datum/shuttle/web_shuttle/proc/build_destinations() From 9292a56201ebe4cc50f7e8326855592a48aaeda1 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Fri, 2 Feb 2018 19:06:07 -0500 Subject: [PATCH 15/74] POLARIS: Silly piloting helmet animation Bonk helmet on shuttle computer to link. No, it doesn't work if you're off the shuttle, no remote info transfer. --- code/modules/shuttles/shuttle.dm | 4 +- code/modules/shuttles/shuttles_web.dm | 46 ++++- icons/obj/piloting_overlay.dmi | Bin 0 -> 140088 bytes maps/southern_cross/items/clothing/sc_head.dm | 168 ++++++++++++++++++ 4 files changed, 214 insertions(+), 4 deletions(-) create mode 100644 icons/obj/piloting_overlay.dmi diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index 8f8de00fc49..ed90e66c6a8 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -127,10 +127,10 @@ depart_time = world.time - on_shuttle_departure(departing) - moving_status = SHUTTLE_INTRANSIT + on_shuttle_departure(departing) + move(departing, interim, direction) interim.shuttle_arrived() diff --git a/code/modules/shuttles/shuttles_web.dm b/code/modules/shuttles/shuttles_web.dm index d16956acdd0..90e51415354 100644 --- a/code/modules/shuttles/shuttles_web.dm +++ b/code/modules/shuttles/shuttles_web.dm @@ -16,6 +16,7 @@ var/autopilot_first_delay = null // If your want your shuttle to stay for a different amount of time for the first time, set this. var/can_rename = TRUE // Lets the pilot rename the shuttle. Only available once. category = /datum/shuttle/web_shuttle + var/list/obj/item/clothing/head/pilot/helmets /datum/shuttle/web_shuttle/New() current_area = locate(current_area) @@ -27,10 +28,12 @@ autopilot_delay = autopilot_first_delay if(!visible_name) visible_name = name + helmets = list() ..() /datum/shuttle/web_shuttle/Destroy() qdel(web_master) + helmets.Cut() return ..() @@ -42,18 +45,30 @@ ..() last_move = world.time +/datum/shuttle/web_shuttle/short_jump() + . = ..() + update_helmets() + +/datum/shuttle/web_shuttle/long_jump() + . = ..() + update_helmets() + /datum/shuttle/web_shuttle/on_shuttle_departure() - ..() + . = ..() web_master.on_shuttle_departure() + update_helmets() /datum/shuttle/web_shuttle/on_shuttle_arrival() - ..() + . = ..() web_master.on_shuttle_arrival() + update_helmets() /datum/shuttle/web_shuttle/proc/build_destinations() return /datum/shuttle/web_shuttle/process() + update_helmets() + if(moving_status == SHUTTLE_IDLE) if(web_master.autopath) // We're currently flying a path. autopilot_say("Continuing route.") @@ -94,6 +109,20 @@ autopilot_say("Taking off.") web_master.process_autopath() +/datum/shuttle/web_shuttle/proc/update_helmets() + for(var/helm in helmets) + if(!helm) + helmets -= helm + continue + var/obj/item/clothing/head/pilot/H = helm + if(!H.shuttle_comp || get_area(H.shuttle_comp) != get_area(H)) + H.shuttle_comp = null + H.audible_message("\The [H] pings as it loses it's connection with the ship.") + H.update_hud("discon") + helmets -= H + else + H.update_hud(moving_status) + /datum/shuttle/web_shuttle/proc/adjust_autopilot(on) if(on) if(autopilot) @@ -156,6 +185,19 @@ for(var/lost in find_sensors) log_debug("[my_area] shuttle computer couldn't find [lost] sensor!") +/obj/machinery/computer/shuttle_control/web/attackby(obj/I, mob/user) + var/datum/shuttle/web_shuttle/shuttle = shuttle_controller.shuttles[shuttle_tag] + if(shuttle && istype(I,/obj/item/clothing/head/pilot)) + var/obj/item/clothing/head/pilot/H = I + H.shuttle_comp = src + shuttle.helmets |= I + to_chat(user,"You register the helmet with the ship's console.") + shuttle.update_helmets() + return + + return ..() + + // Fairly copypasta-y. /obj/machinery/computer/shuttle_control/web/attack_hand(mob/user) if(..(user)) diff --git a/icons/obj/piloting_overlay.dmi b/icons/obj/piloting_overlay.dmi new file mode 100644 index 0000000000000000000000000000000000000000..56074a500456123dd8c2045c1a42d4726c5cb93d GIT binary patch literal 140088 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 Date: Sat, 3 Feb 2018 19:19:26 -0500 Subject: [PATCH 16/74] Make shuttle doors transparent (they do have windows...) --- code/game/machinery/doors/airlock.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 3179e7c2d1b..2d40396d917 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -415,6 +415,8 @@ desc = "It's an extra resilient airlock intended for spacefaring vessels." icon = 'icons/obj/doors/shuttledoors.dmi' explosion_resistance = 20 + opacity = 0 + glass = 1 assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft // Airlock opens from top-bottom instead of left-right. From b69ca8dbddf4eb5481b368f4bf7642c03bc89bf2 Mon Sep 17 00:00:00 2001 From: Leshana Date: Tue, 20 Mar 2018 23:54:42 -0400 Subject: [PATCH 17/74] Move pilot helmets from southern_cross to main files, they are used on multiple maps now. --- .../modules/clothing/head/pilot_helmet.dm | 10 +++------- .../sc_head.dmi => icons/mob/pilot_helmet.dmi | Bin .../mob/species/seromi/pilot_helmet.dmi | Bin icons/obj/clothing/hats.dmi | Bin 99148 -> 99756 bytes maps/southern_cross/southern_cross.dm | 1 - polaris.dme | 1 + 6 files changed, 4 insertions(+), 8 deletions(-) rename maps/southern_cross/items/clothing/sc_head.dm => code/modules/clothing/head/pilot_helmet.dm (93%) rename maps/southern_cross/icons/mob/sc_head.dmi => icons/mob/pilot_helmet.dmi (100%) rename maps/southern_cross/icons/mob/species/teshari/sc_head.dmi => icons/mob/species/seromi/pilot_helmet.dmi (100%) diff --git a/maps/southern_cross/items/clothing/sc_head.dm b/code/modules/clothing/head/pilot_helmet.dm similarity index 93% rename from maps/southern_cross/items/clothing/sc_head.dm rename to code/modules/clothing/head/pilot_helmet.dm index f6be4cac963..feb60ae3a38 100644 --- a/maps/southern_cross/items/clothing/sc_head.dm +++ b/code/modules/clothing/head/pilot_helmet.dm @@ -4,11 +4,10 @@ name = "pilot helmet" desc = "Standard pilot gear. Protects the head from impacts." icon_state = "pilot_helmet1" - item_icons = list(slot_head_str = 'maps/southern_cross/icons/mob/sc_head.dmi') - icon = 'maps/southern_cross/icons/obj/sc_hats.dmi' + item_icons = list(slot_head_str = 'icons/mob/pilot_helmet.dmi') sprite_sheets = list( - "Teshari" = 'maps/southern_cross/icons/mob/species/teshari/sc_head.dmi' - ) + SPECIES_TESHARI = 'icons/mob/species/seromi/pilot_helmet.dmi' + ) flags = THICKMATERIAL armor = list(melee = 20, bullet = 10, laser = 10, energy = 5, bomb = 10, bio = 0, rad = 0) flags_inv = HIDEEARS @@ -190,9 +189,6 @@ name = "pilot helmet" desc = "Standard pilot gear. Protects the head from impacts. This one has a retractable visor" icon_state = "pilot_helmet2" - sprite_sheets = list( - "Teshari" = 'maps/southern_cross/icons/mob/species/teshari/sc_head.dmi' - ) action_button_name = "Toggle Visor" /obj/item/clothing/head/pilot/alt/attack_self(mob/user as mob) diff --git a/maps/southern_cross/icons/mob/sc_head.dmi b/icons/mob/pilot_helmet.dmi similarity index 100% rename from maps/southern_cross/icons/mob/sc_head.dmi rename to icons/mob/pilot_helmet.dmi diff --git a/maps/southern_cross/icons/mob/species/teshari/sc_head.dmi b/icons/mob/species/seromi/pilot_helmet.dmi similarity index 100% rename from maps/southern_cross/icons/mob/species/teshari/sc_head.dmi rename to icons/mob/species/seromi/pilot_helmet.dmi diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 70594a801a83827098b54d31a680367fe86f4b49..a0c2983ea7b59c32ebd6950af263138a5399a62c 100644 GIT binary patch delta 23282 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 delta 22669 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 Date: Wed, 21 Mar 2018 01:39:06 -0500 Subject: [PATCH 18/74] Ports export reports (#5051) * Ports export reports * Absolute pathing, small touchups --- code/game/machinery/computer/supply.dm | 14 + code/game/supplyshuttle.dm | 505 +++++++++++++------------ 2 files changed, 275 insertions(+), 244 deletions(-) diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm index 4bcc43bbecf..e76f4db4683 100644 --- a/code/game/machinery/computer/supply.dm +++ b/code/game/machinery/computer/supply.dm @@ -40,6 +40,7 @@
\nRequest items

View approved orders

View requests

+ \nView export report

Close"} user << browse(dat, "window=computer;size=575x450") @@ -198,6 +199,7 @@ \nOrder items
\n
\nView requests
\n
\nView orders
\n
+ \nView export report
\n
\nClose"} @@ -367,6 +369,18 @@ temp += "
Clear list" temp += "
OK" + else if (href_list["viewexport"]) + temp = "Previous shuttle export report:

" + var/cratecount = 0 + var/totalvalue = 0 + for(var/S in supply_controller.exported_crates) + var/datum/exported_crate/EC = S + cratecount += 1 + totalvalue += EC.value + temp += "[EC.name] exported for [EC.value] supply points
" + temp += "
Shipment of [cratecount] crates exported for [totalvalue] supply points.
" + temp += "
OK" + else if (href_list["rreq"]) var/ordernum = text2num(href_list["rreq"]) temp = "Invalid Request.
" diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index 2efac99edff..3b657e57f2b 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -1,8 +1,8 @@ //Config stuff -#define SUPPLY_DOCKZ 2 //Z-level of the Dock. -#define SUPPLY_STATIONZ 1 //Z-level of the Station. -#define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station -#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock +#define SUPPLY_DOCKZ 2 //Z-level of the Dock. +#define SUPPLY_STATIONZ 1 //Z-level of the Station. +#define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station +#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock //Supply packs are in /code/defines/obj/supplypacks.dm //Computers are in /code/game/machinery/computer/supply.dm @@ -10,306 +10,323 @@ var/datum/controller/supply/supply_controller = new() var/list/mechtoys = list( - /obj/item/toy/prize/ripley, - /obj/item/toy/prize/fireripley, - /obj/item/toy/prize/deathripley, - /obj/item/toy/prize/gygax, - /obj/item/toy/prize/durand, - /obj/item/toy/prize/honk, - /obj/item/toy/prize/marauder, - /obj/item/toy/prize/seraph, - /obj/item/toy/prize/mauler, - /obj/item/toy/prize/odysseus, - /obj/item/toy/prize/phazon + /obj/item/toy/prize/ripley, + /obj/item/toy/prize/fireripley, + /obj/item/toy/prize/deathripley, + /obj/item/toy/prize/gygax, + /obj/item/toy/prize/durand, + /obj/item/toy/prize/honk, + /obj/item/toy/prize/marauder, + /obj/item/toy/prize/seraph, + /obj/item/toy/prize/mauler, + /obj/item/toy/prize/odysseus, + /obj/item/toy/prize/phazon ) /obj/item/weapon/paper/manifest - name = "supply manifest" - var/is_copy = 1 + name = "supply manifest" + var/is_copy = 1 /area/supply/station - name = "Supply Shuttle" - icon_state = "shuttle3" - requires_power = 0 - base_turf = /turf/space + name = "Supply Shuttle" + icon_state = "shuttle3" + requires_power = 0 + base_turf = /turf/space /area/supply/dock - name = "Supply Shuttle" - icon_state = "shuttle3" - requires_power = 0 - base_turf = /turf/space + name = "Supply Shuttle" + icon_state = "shuttle3" + requires_power = 0 + base_turf = /turf/space /obj/structure/plasticflaps //HOW DO YOU CALL THOSE THINGS ANYWAY - name = "\improper plastic flaps" - desc = "Completely impassable - or are they?" - icon = 'icons/obj/stationobjs.dmi' //Change this. - icon_state = "plasticflaps" - density = 0 - anchored = 1 - layer = 4 - explosion_resistance = 5 - var/list/mobs_can_pass = list( - /mob/living/bot, - /mob/living/simple_animal/slime, - /mob/living/simple_animal/mouse, - /mob/living/silicon/robot/drone - ) + name = "\improper plastic flaps" + desc = "Completely impassable - or are they?" + icon = 'icons/obj/stationobjs.dmi' //Change this. + icon_state = "plasticflaps" + density = 0 + anchored = 1 + layer = 4 + explosion_resistance = 5 + var/list/mobs_can_pass = list( + /mob/living/bot, + /mob/living/simple_animal/slime, + /mob/living/simple_animal/mouse, + /mob/living/silicon/robot/drone + ) /obj/structure/plasticflaps/attackby(obj/item/P, mob/user) - if(istype(P, /obj/item/weapon/wirecutters)) - playsound(src, P.usesound, 50, 1) - user << "You start to cut the plastic flaps." - if(do_after(user, 10 * P.toolspeed)) - user << "You cut the plastic flaps." - var/obj/item/stack/material/plastic/A = new /obj/item/stack/material/plastic( src.loc ) - A.amount = 4 - qdel(src) - return - else - return + if(istype(P, /obj/item/weapon/wirecutters)) + playsound(src, P.usesound, 50, 1) + user << "You start to cut the plastic flaps." + if(do_after(user, 10 * P.toolspeed)) + user << "You cut the plastic flaps." + var/obj/item/stack/material/plastic/A = new /obj/item/stack/material/plastic( src.loc ) + A.amount = 4 + qdel(src) + return + else + return /obj/structure/plasticflaps/CanPass(atom/A, turf/T) - if(istype(A) && A.checkpass(PASSGLASS)) - return prob(60) + if(istype(A) && A.checkpass(PASSGLASS)) + return prob(60) - var/obj/structure/bed/B = A - if (istype(A, /obj/structure/bed) && B.has_buckled_mobs())//if it's a bed/chair and someone is buckled, it will not pass - return 0 + var/obj/structure/bed/B = A + if (istype(A, /obj/structure/bed) && B.has_buckled_mobs())//if it's a bed/chair and someone is buckled, it will not pass + return 0 - if(istype(A, /obj/vehicle)) //no vehicles - return 0 + if(istype(A, /obj/vehicle)) //no vehicles + return 0 - var/mob/living/M = A - if(istype(M)) - if(M.lying) - return ..() - for(var/mob_type in mobs_can_pass) - if(istype(A, mob_type)) - return ..() - return issmall(M) + var/mob/living/M = A + if(istype(M)) + if(M.lying) + return ..() + for(var/mob_type in mobs_can_pass) + if(istype(A, mob_type)) + return ..() + return issmall(M) - return ..() + return ..() /obj/structure/plasticflaps/ex_act(severity) - switch(severity) - if (1) - qdel(src) - if (2) - if (prob(50)) - qdel(src) - if (3) - if (prob(5)) - qdel(src) + switch(severity) + if (1) + qdel(src) + if (2) + if (prob(50)) + qdel(src) + if (3) + if (prob(5)) + qdel(src) /obj/structure/plasticflaps/mining //A specific type for mining that doesn't allow airflow because of them damn crates - name = "airtight plastic flaps" - desc = "Heavy duty, airtight, plastic flaps." + name = "airtight plastic flaps" + desc = "Heavy duty, airtight, plastic flaps." - New() //set the turf below the flaps to block air - var/turf/T = get_turf(loc) - if(T) - T.blocks_air = 1 - ..() +/obj/structure/plasticflaps/mining/New() //set the turf below the flaps to block air + var/turf/T = get_turf(loc) + if(T) + T.blocks_air = 1 + ..() - Destroy() //lazy hack to set the turf to allow air to pass if it's a simulated floor - var/turf/T = get_turf(loc) - if(T) - if(istype(T, /turf/simulated/floor)) - T.blocks_air = 0 - ..() +/obj/structure/plasticflaps/mining/Destroy() //lazy hack to set the turf to allow air to pass if it's a simulated floor + var/turf/T = get_turf(loc) + if(T && istype(T, /turf/simulated/floor)) + T.blocks_air = 0 + ..() /* /obj/effect/marker/supplymarker - icon_state = "X" - icon = 'icons/misc/mark.dmi' - name = "X" - invisibility = 101 - anchored = 1 - opacity = 0 + icon_state = "X" + icon = 'icons/misc/mark.dmi' + name = "X" + invisibility = 101 + anchored = 1 + opacity = 0 */ /datum/supply_order - var/ordernum - var/datum/supply_packs/object = null - var/orderedby = null - var/comment = null + var/ordernum + var/datum/supply_packs/object = null + var/orderedby = null + var/comment = null + +/datum/exported_crate + var/name + var/value /datum/controller/supply - //supply points - var/points = 50 - var/points_per_process = 1.5 - var/points_per_slip = 2 - var/points_per_platinum = 5 // 5 points per sheet - var/points_per_phoron = 5 - var/points_per_money = 0.02 - //control - var/ordernum - var/list/shoppinglist = list() - var/list/requestlist = list() - var/list/supply_packs = list() - //shuttle movement - var/movetime = 1200 - var/datum/shuttle/ferry/supply/shuttle + //supply points + var/points = 50 + var/points_per_process = 1.5 + var/points_per_slip = 2 + var/points_per_platinum = 5 // 5 points per sheet + var/points_per_phoron = 5 + var/points_per_money = 0.02 + //control + var/ordernum + var/list/shoppinglist = list() + var/list/requestlist = list() + var/list/supply_packs = list() + var/list/exported_crates = list() + //shuttle movement + var/movetime = 1200 + var/datum/shuttle/ferry/supply/shuttle - New() - ordernum = rand(1,9000) +/datum/controller/supply/New() + ordernum = rand(1,9000) - for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs)) - var/datum/supply_packs/P = new typepath() - supply_packs[P.name] = P + for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs)) + var/datum/supply_packs/P = new typepath() + supply_packs[P.name] = P - // Supply shuttle ticker - handles supply point regeneration - // This is called by the process scheduler every thirty seconds - proc/process() - points += points_per_process +// Supply shuttle ticker - handles supply point regeneration +// This is called by the process scheduler every thirty seconds +/datum/controller/supply/proc/process() + points += points_per_process - //To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types. - proc/forbidden_atoms_check(atom/A) - if(istype(A,/mob/living)) - return 1 - if(istype(A,/obj/item/weapon/disk/nuclear)) - return 1 - if(istype(A,/obj/machinery/nuclearbomb)) - return 1 - if(istype(A,/obj/item/device/radio/beacon)) - return 1 +//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types. +/datum/controller/supply/proc/forbidden_atoms_check(atom/A) + if(isliving(A)) + return 1 + if(istype(A,/obj/item/weapon/disk/nuclear)) + return 1 + if(istype(A,/obj/machinery/nuclearbomb)) + return 1 + if(istype(A,/obj/item/device/radio/beacon)) + return 1 - for(var/i=1, i<=A.contents.len, i++) - var/atom/B = A.contents[i] - if(.(B)) - return 1 + for(var/i=1, i<=A.contents.len, i++) + var/atom/B = A.contents[i] + if(.(B)) + return 1 - //Sellin - proc/sell() - var/area/area_shuttle = shuttle.get_location_area() - if(!area_shuttle) return +//Sellin +/datum/controller/supply/proc/sell() + var/area/area_shuttle = shuttle.get_location_area() + if(!area_shuttle) return - callHook("sell_shuttle", list(area_shuttle)); + callHook("sell_shuttle", list(area_shuttle)); - var/phoron_count = 0 - var/plat_count = 0 - var/money_count = 0 + var/phoron_count = 0 + var/plat_count = 0 + var/money_count = 0 - for(var/atom/movable/MA in area_shuttle) - if(MA.anchored) continue + exported_crates = list() - // Must be in a crate! - if(istype(MA,/obj/structure/closet/crate)) - var/obj/structure/closet/crate/CR = MA - callHook("sell_crate", list(CR, area_shuttle)) + for(var/atom/movable/MA in area_shuttle) + if(MA.anchored) continue - points += CR.points_per_crate - var/find_slip = 1 + // Must be in a crate! + if(istype(MA,/obj/structure/closet/crate)) + var/oldpoints = points + var/oldphoron = phoron_count + var/oldplatinum = plat_count + var/oldmoney = money_count - for(var/atom in CR) - // Sell manifests - var/atom/A = atom - if(find_slip && istype(A,/obj/item/weapon/paper/manifest)) - var/obj/item/weapon/paper/manifest/slip = A - if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense - points += points_per_slip - find_slip = 0 - continue + var/obj/structure/closet/crate/CR = MA + callHook("sell_crate", list(CR, area_shuttle)) - // Sell phoron and platinum - if(istype(A, /obj/item/stack)) - var/obj/item/stack/P = A - switch(P.get_material_name()) - if("phoron") phoron_count += P.get_amount() - if("platinum") plat_count += P.get_amount() + points += CR.points_per_crate + var/find_slip = 1 - //Sell spacebucks - if(istype(A, /obj/item/weapon/spacecash)) - var/obj/item/weapon/spacecash/cashmoney = A - money_count += cashmoney.worth - qdel(MA) + for(var/atom in CR) + // Sell manifests + var/atom/A = atom + if(find_slip && istype(A,/obj/item/weapon/paper/manifest)) + var/obj/item/weapon/paper/manifest/slip = A + if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense + points += points_per_slip + find_slip = 0 + continue - if(phoron_count) - points += phoron_count * points_per_phoron + // Sell phoron and platinum + if(istype(A, /obj/item/stack)) + var/obj/item/stack/P = A + switch(P.get_material_name()) + if("phoron") phoron_count += P.get_amount() + if("platinum") plat_count += P.get_amount() - if(plat_count) - points += plat_count * points_per_platinum + //Sell spacebucks + if(istype(A, /obj/item/weapon/spacecash)) + var/obj/item/weapon/spacecash/cashmoney = A + money_count += cashmoney.worth - if(money_count) - points += money_count * points_per_money + var/datum/exported_crate/EC = new /datum/exported_crate() + EC.name = CR.name + EC.value = points - oldpoints + EC.value += (phoron_count - oldphoron) * points_per_phoron + EC.value += (plat_count - oldplatinum) * points_per_platinum + EC.value += (money_count - oldmoney) * points_per_money + exported_crates += EC - //Buyin - proc/buy() - if(!shoppinglist.len) return + qdel(MA) - var/orderedamount = shoppinglist.len + points += phoron_count * points_per_phoron + points += plat_count * points_per_platinum + points += money_count * points_per_money - var/area/area_shuttle = shuttle.get_location_area() - if(!area_shuttle) return +//Buyin +/datum/controller/supply/proc/buy() + if(!shoppinglist.len) + return - var/list/clear_turfs = list() + var/orderedamount = shoppinglist.len - for(var/turf/T in area_shuttle) - if(T.density) continue - var/contcount - for(var/atom/A in T.contents) - if(!A.simulated) - continue - contcount++ - if(contcount) - continue - clear_turfs += T + var/area/area_shuttle = shuttle.get_location_area() + if(!area_shuttle) + return - for(var/S in shoppinglist) - if(!clear_turfs.len) break - var/i = rand(1,clear_turfs.len) - var/turf/pickedloc = clear_turfs[i] - clear_turfs.Cut(i,i+1) - shoppinglist -= S + var/list/clear_turfs = list() - var/datum/supply_order/SO = S - var/datum/supply_packs/SP = SO.object + for(var/turf/T in area_shuttle) + if(T.density) + continue + var/contcount + for(var/atom/A in T.contents) + if(!A.simulated) + continue + contcount++ + if(contcount) + continue + clear_turfs += T - var/obj/A = new SP.containertype(pickedloc) - A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]" + for(var/S in shoppinglist) + if(!clear_turfs.len) break + var/i = rand(1,clear_turfs.len) + var/turf/pickedloc = clear_turfs[i] + clear_turfs.Cut(i,i+1) + shoppinglist -= S - //supply manifest generation begin + var/datum/supply_order/SO = S + var/datum/supply_packs/SP = SO.object - var/obj/item/weapon/paper/manifest/slip - if(!SP.contraband) - slip = new /obj/item/weapon/paper/manifest(A) - slip.is_copy = 0 - slip.info = "

[command_name()] Shipping Manifest



" - slip.info +="Order #[SO.ordernum]
" - slip.info +="Destination: [station_name()]
" - slip.info +="[orderedamount] PACKAGES IN THIS SHIPMENT
" - slip.info +="CONTENTS:
    " + var/obj/A = new SP.containertype(pickedloc) + A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]" - //spawn the stuff, finish generating the manifest while you're at it - if(SP.access) - if(isnum(SP.access)) - A.req_access = list(SP.access) - else if(islist(SP.access)) - var/list/L = SP.access // access var is a plain var, we need a list - A.req_access = L.Copy() - else - world << "Supply pack with invalid access restriction [SP.access] encountered!" + //supply manifest generation begin + var/obj/item/weapon/paper/manifest/slip + if(!SP.contraband) + slip = new /obj/item/weapon/paper/manifest(A) + slip.is_copy = 0 + slip.info = "

    [command_name()] Shipping Manifest



    " + slip.info +="Order #[SO.ordernum]
    " + slip.info +="Destination: [station_name()]
    " + slip.info +="[orderedamount] PACKAGES IN THIS SHIPMENT
    " + slip.info +="CONTENTS:
      " - var/list/contains - if(istype(SP,/datum/supply_packs/randomised)) - var/datum/supply_packs/randomised/SPR = SP - contains = list() - if(SPR.contains.len) - for(var/j=1,j<=SPR.num_contained,j++) - contains += pick(SPR.contains) - else - contains = SP.contains + //spawn the stuff, finish generating the manifest while you're at it + if(SP.access) + if(isnum(SP.access)) + A.req_access = list(SP.access) + else if(islist(SP.access)) + var/list/L = SP.access // access var is a plain var, we need a list + A.req_access = L.Copy() + else + log_debug("Supply pack with invalid access restriction [SP.access] encountered!") - for(var/typepath in contains) - if(!typepath) continue - var/number_of_items = max(1, contains[typepath]) - for(var/j = 1 to number_of_items) - var/atom/B2 = new typepath(A) - if(slip) slip.info += "
    • [B2.name]
    • " //add the item to the manifest + var/list/contains + if(istype(SP,/datum/supply_packs/randomised)) + var/datum/supply_packs/randomised/SPR = SP + contains = list() + if(SPR.contains.len) + for(var/j=1,j<=SPR.num_contained,j++) + contains += pick(SPR.contains) + else + contains = SP.contains - //manifest finalisation - if(slip) - slip.info += "

    " - slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS
    " + for(var/typepath in contains) + if(!typepath) continue + var/number_of_items = max(1, contains[typepath]) + for(var/j = 1 to number_of_items) + var/atom/B2 = new typepath(A) + if(slip) slip.info += "
  • [B2.name]
  • " //add the item to the manifest - return \ No newline at end of file + //manifest finalisation + if(slip) + slip.info += "

" + slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS
" + + return From eabec5fb1ee38492baa8d82d56491264b3cc5643 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 30 Jan 2018 21:13:50 -0500 Subject: [PATCH 19/74] POLARIS: No string compare for assistants --- .../client/preference_setup/occupation/occupation.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index 18e1be05f48..1a09ee6ae96 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -94,7 +94,7 @@ if(job.minimum_character_age && user.client && (user.client.prefs.age < job.minimum_character_age)) . += "[rank] \[MINIMUM CHARACTER AGE: [job.minimum_character_age]]" continue - if((pref.job_civilian_low & ASSISTANT) && (rank != "Assistant")) + if((pref.job_civilian_low & ASSISTANT) && job.flag != ASSISTANT) . += "[rank]" continue if((rank in command_positions) || (rank == "AI"))//Bold head jobs @@ -106,7 +106,7 @@ . += "" - if(rank == "Assistant")//Assistant is special + if(job.flag == ASSISTANT)//Assistant is special if(pref.job_civilian_low & ASSISTANT) . += " \[Yes]" else @@ -180,7 +180,7 @@ if(!job) return 0 - if(role == "Assistant") + if(job.flag == ASSISTANT) if(pref.job_civilian_low & job.flag) pref.job_civilian_low &= ~job.flag else From 21ce4159b7cf4e6042e7ada950e7f6c2f09e0f9b Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 17 Feb 2018 21:55:59 -0600 Subject: [PATCH 20/74] Make turf obfuscation lists lazy --- code/modules/mob/freelook/chunk.dm | 2 ++ code/modules/mob/freelook/update_triggers.dm | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/freelook/chunk.dm b/code/modules/mob/freelook/chunk.dm index 7c50bd3135a..41439b4adc7 100644 --- a/code/modules/mob/freelook/chunk.dm +++ b/code/modules/mob/freelook/chunk.dm @@ -100,6 +100,7 @@ for(var/turf in visRemoved) var/turf/t = turf if(obscuredTurfs[t]) + LAZYINITLIST(t.obfuscations) if(!t.obfuscations[obfuscation.type]) var/image/ob_image = image(obfuscation.icon, t, obfuscation.icon_state, OBFUSCATION_LAYER) ob_image.plane = PLANE_FULLSCREEN @@ -141,6 +142,7 @@ for(var/turf in obscuredTurfs) var/turf/t = turf + LAZYINITLIST(t.obfuscations) if(!t.obfuscations[obfuscation.type]) var/image/ob_image = image(obfuscation.icon, t, obfuscation.icon_state, OBFUSCATION_LAYER) ob_image.plane = PLANE_FULLSCREEN diff --git a/code/modules/mob/freelook/update_triggers.dm b/code/modules/mob/freelook/update_triggers.dm index 482025426eb..0b31e24cce2 100644 --- a/code/modules/mob/freelook/update_triggers.dm +++ b/code/modules/mob/freelook/update_triggers.dm @@ -8,7 +8,7 @@ VN.updateVisibility(A, opacity_check) /turf - var/list/image/obfuscations = new() + var/list/image/obfuscations /turf/drain_power() return -1 From 298ba7ea4b9f0741019db912579b724dd2081b09 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Wed, 21 Feb 2018 23:23:02 -0500 Subject: [PATCH 21/74] Improve two image cleanups --- code/modules/mob/animations.dm | 23 +++++++++++++++-------- code/modules/mob/living/say.dm | 28 +++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm index 9074357afaa..edffbb5a874 100644 --- a/code/modules/mob/animations.dm +++ b/code/modules/mob/animations.dm @@ -167,7 +167,17 @@ note dizziness decrements automatically in the mob's Life() proc. /mob/living/do_attack_animation(atom/A) ..() - is_floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. + //Check for clients with pref enabled + var/list/viewing = list() + for(var/m in viewers(A)) + var/mob/M = m + var/client/C = M.client + if(C && C.is_preference_enabled(/datum/client_preference/attack_icons)) + viewing += M.client + + //Animals attacking each other in the distance, probably. Forgeddaboutit. + if(!viewing.len) + return FALSE // What icon do we use for the attack? var/obj/used_item @@ -180,6 +190,9 @@ note dizziness decrements automatically in the mob's Life() proc. if(!used_item && !(attack_icon && attack_icon_state)) return FALSE //Didn't find an item, not doing animation. + // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. + is_floating = 0 + var/image/I if(used_item) //Found an in-hand item to animate @@ -192,13 +205,7 @@ note dizziness decrements automatically in the mob's Life() proc. I = image(attack_icon, A, attack_icon_state, A.layer + 1) I.dir = dir - //Check for clients with pref enabled - var/list/viewing = list() - for(var/m in viewers(A)) - var/mob/M = m - var/client/C = M.client - if(C && C.is_preference_enabled(/datum/client_preference/attack_icons)) - viewing += M.client + // Show the overlay to the clients flick_overlay(I, viewing, 5, TRUE) // 5 ticks/half a second // Set the direction of the icon animation. diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index d022ef71b8e..952d3dc9f17 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -298,11 +298,14 @@ proc/get_radio_key_from_channel(var/channel) else return 1 //If we're in nullspace, then forget it. + //Remember the speech images so we can remove them later and they can get GC'd + var/list/images_to_clients = list() + //The 'post-say' static speech bubble var/speech_bubble_test = say_test(message) var/speech_type = speech_bubble_appearance() var/image/speech_bubble = image('icons/mob/talk.dmi',src,"[speech_type][speech_bubble_test]") - spawn(30) qdel(speech_bubble) + images_to_clients[speech_bubble] = list() // Attempt Multi-Z Talking var/mob/above = src.shadow @@ -311,7 +314,7 @@ proc/get_radio_key_from_channel(var/channel) if(ST) var/list/results = get_mobs_and_objs_in_view_fast(ST, world.view) var/image/z_speech_bubble = image('icons/mob/talk.dmi', above, "h[speech_bubble_test]") - spawn(30) qdel(z_speech_bubble) + images_to_clients[z_speech_bubble] = list() for(var/item in results["mobs"]) if(item != above && !(item in listening)) listening[item] = z_speech_bubble @@ -326,12 +329,17 @@ proc/get_radio_key_from_channel(var/channel) var/dst = get_dist(get_turf(M),get_turf(src)) if(dst <= message_range || (M.stat == DEAD && !forbid_seeing_deadchat)) //Inside normal message range, or dead with ears (handled in the view proc) - M << (listening[M] || speech_bubble) // Send the image attached to shadow mob if available + if(M.client) + var/image/I1 = listening[M] || speech_bubble + images_to_clients[I1] |= M.client + M << I1 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 << (listening[M] || speech_bubble) // Send the image attached to shadow mob if available + if(M.client) + var/image/I2 = listening[M] || speech_bubble + images_to_clients[I2] |= M.client + M << I2 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) @@ -344,6 +352,16 @@ proc/get_radio_key_from_channel(var/channel) if(dst <= message_range) O.hear_talk(src, message, verb, speaking) + //Remove all those images. At least it's just ONE spawn this time. + spawn(30) + for(var/img in images_to_clients) + var/image/I = img + var/list/clients_from_image = images_to_clients[I] + for(var/client in clients_from_image) + var/client/C = client + C.images -= I + qdel(I) + //Log the message to file if(whispering) log_whisper(message,src) From 2dd109e9896f132360b159b291a4b9fb34156419 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Thu, 22 Feb 2018 22:36:39 -0500 Subject: [PATCH 22/74] POLARIS: zshadows should be as invisible as their origin --- code/modules/multiz/zshadow.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/multiz/zshadow.dm b/code/modules/multiz/zshadow.dm index 10af55f5a3b..85685b3d6a2 100644 --- a/code/modules/multiz/zshadow.dm +++ b/code/modules/multiz/zshadow.dm @@ -56,6 +56,7 @@ overlays = M.overlays transform = M.transform dir = M.dir + invisibility = M.invisibility if(shadow) shadow.sync_icon(src) From fab0800b51132ffe1b92bcaa68adf80e819f051e Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Thu, 22 Feb 2018 23:01:16 -0500 Subject: [PATCH 23/74] POLARIS: Allow alteration of mob default see_invisible --- code/modules/mob/living/carbon/human/life.dm | 10 +++++----- code/modules/mob/living/living_defines.dm | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index b27f98bc40c..1d6bc938f5d 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1161,7 +1161,7 @@ else sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS) - see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING + see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : see_invisible_default if(XRAY in mutations) sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS @@ -1173,7 +1173,7 @@ if(R && R.word1 == cultwords["see"] && R.word2 == cultwords["hell"] && R.word3 == cultwords["join"]) see_invisible = SEE_INVISIBLE_CULT else - see_invisible = SEE_INVISIBLE_LIVING + see_invisible = see_invisible_default seer = 0 if(!seedarkness) @@ -1184,7 +1184,7 @@ else sight = species.get_vision_flags(src) see_in_dark = species.darksight - see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING + see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : see_invisible_default var/tmp/glasses_processed = 0 var/obj/item/weapon/rig/rig = back @@ -1205,7 +1205,7 @@ if(!glasses_processed && (species.get_vision_flags(src) > 0)) sight |= species.get_vision_flags(src) if(!seer && !glasses_processed && seedarkness) - see_invisible = SEE_INVISIBLE_LIVING + see_invisible = see_invisible_default if(healths) if (chem_effects[CE_PAINKILLER] > 100) @@ -1385,7 +1385,7 @@ if(G.see_invisible >= 0) see_invisible = G.see_invisible else if(!druggy && !seer) - see_invisible = SEE_INVISIBLE_LIVING + see_invisible = see_invisible_default /mob/living/carbon/human/handle_random_events() if(inStasisNow()) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 23dbb6fc09d..9739e596b8e 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -55,5 +55,7 @@ var/glow_intensity = null var/glow_color = "#FFFFFF" // The color they're glowing! + var/see_invisible_default = SEE_INVISIBLE_LIVING + var/list/hud_list //Holder for health hud, status hud, wanted hud, etc (not like inventory slots) var/has_huds = FALSE //Whether or not we should bother initializing the above list From 286a8651d26b14fe80cde1f11a88c17366c71894 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Fri, 23 Feb 2018 15:56:16 -0500 Subject: [PATCH 24/74] say() safety check on client Spawn keeps it from destroying all say(), thankfully, but needs to be fixed. --- code/modules/mob/living/say.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 952d3dc9f17..9e4ede05a13 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -359,7 +359,8 @@ proc/get_radio_key_from_channel(var/channel) var/list/clients_from_image = images_to_clients[I] for(var/client in clients_from_image) var/client/C = client - C.images -= I + if(C) //Could have disconnected after message sent, before removing bubble. + C.images -= I qdel(I) //Log the message to file From c9f9d984d7a8b45c573e82c8af28ef96c84c02b0 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 12 Mar 2018 21:06:18 -0400 Subject: [PATCH 25/74] POLARIS: Reduce double admin logs --- code/modules/admin/admin.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index a9075a84307..a31748d676d 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -6,7 +6,7 @@ var/global/floorIsLava = 0 //////////////////////////////// /proc/message_admins(var/msg) msg = "ADMIN LOG: [msg]" - log_adminwarn(msg) + //log_adminwarn(msg) //log_and_message_admins is for this for(var/client/C in admins) if((R_ADMIN|R_MOD) & C.holder.rights) C << msg From c492d1a21b9aebc2cca006aa95ae389e6f7552ce Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 12 Mar 2018 21:16:47 -0400 Subject: [PATCH 26/74] POLARIS: Clean up adminpm logs --- code/_helpers/logging.dm | 5 +++++ code/modules/admin/verbs/adminpm.dm | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index f9b7a6e3ef7..6644cc2efee 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -25,6 +25,11 @@ if (config.log_admin) diary << "\[[time_stamp()]]ADMIN: [text][log_end]" +/proc/log_adminpm(text, client/source, client/dest) + admin_log.Add(text) + if (config.log_admin) + diary << "\[[time_stamp()]]ADMINPM: [key_name(source)]->[key_name(dest)]: [html_decode(text)][log_end]" + /proc/log_debug(text) if (config.log_debug) debug_log << "\[[time_stamp()]]DEBUG: [text][log_end]" diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index dcaa7454857..4ff94877f42 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -104,7 +104,7 @@ if(C.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping)) C << 'sound/effects/adminhelp.ogg' - log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]") + log_adminpm(msg,src,C) send2adminirc("Reply: [key_name(src)]->[key_name(C)]: [html_decode(msg)]") //we don't use message_admins here because the sender/receiver might get it too From cad8df658e0c5d8b855b8c3f070131b74ed7412d Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Thu, 15 Mar 2018 23:47:00 -0400 Subject: [PATCH 27/74] POLARIS: Communicator small refactor --- code/game/objects/items/devices/communicator/UI.dm | 6 +----- .../items/devices/communicator/communicator.dm | 12 ++++++------ code/modules/mob/living/silicon/ai/ai.dm | 2 +- code/modules/mob/living/silicon/robot/robot.dm | 2 +- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/code/game/objects/items/devices/communicator/UI.dm b/code/game/objects/items/devices/communicator/UI.dm index cbdae90c903..f2d3fd39b6f 100644 --- a/code/game/objects/items/devices/communicator/UI.dm +++ b/code/game/objects/items/devices/communicator/UI.dm @@ -134,11 +134,7 @@ if(href_list["rename"]) var/new_name = sanitizeSafe(input(usr,"Please enter your name.","Communicator",usr.name) ) if(new_name) - owner = new_name - name = "[owner]'s [initial(name)]" - if(camera) - camera.name = name - camera.c_tag = name + register_device(new_name) if(href_list["toggle_visibility"]) switch(network_visibility) diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm index f809bcb9b2d..7342988916b 100644 --- a/code/game/objects/items/devices/communicator/communicator.dm +++ b/code/game/objects/items/devices/communicator/communicator.dm @@ -75,12 +75,12 @@ var/global/list/obj/item/device/communicator/all_communicators = list() //This is a pretty terrible way of doing this. spawn(5 SECONDS) //Wait for our mob to finish spawning. if(ismob(loc)) - register_device(loc) + register_device(loc.name) initialize_exonet(loc) else if(istype(loc, /obj/item/weapon/storage)) var/obj/item/weapon/storage/S = loc if(ismob(S.loc)) - register_device(S.loc) + register_device(S.loc.name) initialize_exonet(S.loc) // Proc: examine() @@ -268,12 +268,12 @@ var/global/list/obj/item/device/communicator/all_communicators = list() // Proc: register_device() // Parameters: 1 (user - the person to use their name for) // Description: Updates the owner's name and the device's name. -/obj/item/device/communicator/proc/register_device(mob/user) - if(!user) +/obj/item/device/communicator/proc/register_device(new_name) + if(!new_name) return - owner = user.name + owner = new_name - name = "[owner]'s [initial(name)]" + name = "[new_name]'s [initial(name)]" if(camera) camera.name = name camera.c_tag = name diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 2bdcf1b912b..2b11059ff9c 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -258,7 +258,7 @@ var/list/ai_verbs_default = list( aiPDA.name = pickedName + " (" + aiPDA.ownjob + ")" if(aiCommunicator) - aiCommunicator.register_device(src) + aiCommunicator.register_device(src.name) /* The AI Power supply is a dummy object used for powering the AI since only machinery should be using power. diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 589f410f012..be725f353d6 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -210,7 +210,7 @@ /mob/living/silicon/robot/proc/setup_communicator() if (!communicator) communicator = new/obj/item/device/communicator/integrated(src) - communicator.register_device(src, "[modtype] [braintype]") + communicator.register_device(src.name, "[modtype] [braintype]") //If there's an MMI in the robot, have it ejected when the mob goes away. --NEO //Improved /N From 71dac8ae261443c923ba112d3c11e434468dc8fb Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Fri, 16 Mar 2018 00:10:43 -0400 Subject: [PATCH 28/74] POLARIS: UI Tweak involving species rarity --- .../modules/client/preference_setup/general/03_body.dm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 432dfdbb6ea..cfe00143694 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -741,7 +741,15 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O dat += "Language: [current_species.species_language]
" dat += "" if(current_species.spawn_flags & SPECIES_CAN_JOIN) - dat += "
Often present on human stations." + switch(current_species.rarity_value) + if(1 to 2) + dat += "
Often present on human stations." + if(3 to 4) + dat += "
Rarely present on human stations." + if(5) + dat += "
Unheard of on human stations." + else + dat += "
May be present on human stations." if(current_species.spawn_flags & SPECIES_IS_WHITELISTED) dat += "
Whitelist restricted." if(!current_species.has_organ[O_HEART]) From 723de2816557878e553113c52f3b7e31e6a877da Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Thu, 15 Mar 2018 23:56:43 -0400 Subject: [PATCH 29/74] POLARIS: Allow species-specific statpanels --- code/modules/mob/living/carbon/human/human.dm | 2 ++ code/modules/mob/living/carbon/human/species/species.dm | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 09f6c62276f..57e2014871c 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -94,6 +94,8 @@ stat("Chemical Storage", mind.changeling.chem_charges) stat("Genetic Damage Time", mind.changeling.geneticdamage) stat("Re-Adaptations", "[mind.changeling.readapts]/[mind.changeling.max_readapts]") + if(species) + species.Stat(src) /mob/living/carbon/human/ex_act(severity) if(!blinded) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 39b84609071..787ec957192 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -422,3 +422,7 @@ // Used to override normal fall behaviour. Use only when the species does fall down a level. /datum/species/proc/fall_impact_special(var/mob/living/carbon/human/H, var/atom/A) return FALSE + +// Allow species to display interesting information in the human stat panels +/datum/species/proc/Stat(var/mob/living/carbon/human/H) + return From 4e39bfefe75c87aa184e692d769d1c150b9cf142 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 17 Mar 2018 19:47:31 -0400 Subject: [PATCH 30/74] POLARIS: "0x32" is not a valid single-bit flag --- code/__defines/mobs.dm | 2 +- code/game/gamemodes/changeling/powers/revive.dm | 2 +- code/modules/mob/living/carbon/metroid/life.dm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 9343a4590ff..bb17deacf49 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -10,7 +10,7 @@ #define CANPUSH 0x8 #define LEAPING 0x10 #define HIDING 0x20 -#define PASSEMOTES 0x32 // Mob has a cortical borer or holders inside of it that need to see emotes. +#define PASSEMOTES 0x40 // Mob has a cortical borer or holders inside of it that need to see emotes. #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 diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index ab8111000d1..0da6c3c3d56 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -33,7 +33,7 @@ H.restore_all_organs(ignore_prosthetic_prefs=1) //Covers things like fractures and other things not covered by the above. H.restore_blood() H.mutations.Remove(HUSK) - H.status_flags -= DISFIGURED + H.status_flags &= ~DISFIGURED H.update_icons_body() for(var/limb in H.organs_by_name) var/obj/item/organ/external/current_limb = H.organs_by_name[limb] diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index 0f393a9417d..5cf6395b7d6 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -100,7 +100,7 @@ src.lying = 1 src.blinded = 1 else - if (src.paralysis || src.stunned || src.weakened || (status_flags && FAKEDEATH)) //Stunned etc. + if (src.paralysis || src.stunned || src.weakened || (status_flags & FAKEDEATH)) //Stunned etc. if (src.stunned > 0) src.stat = 0 if (src.weakened > 0) From 45ec49661d07fd4a0c4786ebf3f8d9fc4d601ce8 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 11:26:56 -0400 Subject: [PATCH 31/74] POLARIS: Lazylen species restricted list --- code/modules/clothing/clothing.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index ff8d0d94c64..ee815fd5584 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -57,7 +57,7 @@ if (!..()) return 0 - if(species_restricted && istype(M,/mob/living/carbon/human)) + if(LAZYLEN(species_restricted) && istype(M,/mob/living/carbon/human)) var/exclusive = null var/wearable = null var/mob/living/carbon/human/H = M From 3beaefd6793915a4b7f95653368d8fdd1242ab6c Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 10 Mar 2018 18:39:11 -0500 Subject: [PATCH 32/74] POLARIS: Prevent ghosts from ejecting borgs from rechargers --- code/game/machinery/rechargestation.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index d4d3cedb476..5e0f181d82d 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -289,7 +289,7 @@ set name = "Eject Recharger" set src in oview(1) - if(usr.incapacitated()) + if(usr.incapacitated() || !isliving(usr)) return go_out() @@ -301,8 +301,9 @@ set name = "Enter Recharger" set src in oview(1) - if(!usr.incapacitated()) + if(usr.incapacitated() || !isliving(usr)) return + go_in(usr) /obj/machinery/recharge_station/ghost_pod_recharger From 2115f6fad2720d5817f01cb4e8e1d83a235da4d9 Mon Sep 17 00:00:00 2001 From: Aronai Sieyes Date: Sat, 17 Mar 2018 13:02:50 -0400 Subject: [PATCH 33/74] POLARIS: Make borg recharger test more robust --- code/game/machinery/rechargestation.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 5e0f181d82d..b1631718982 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -254,7 +254,7 @@ else if(istype(L, /mob/living/carbon/human)) var/mob/living/carbon/human/H = L - if(!isnull(H.internal_organs_by_name["cell"])) + if(H.isSynthetic()) add_fingerprint(H) H.reset_view(src) H.forceMove(src) From 4c016bc6911af11c8dd1a3cc21b7ba6465b36c61 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sun, 18 Mar 2018 17:25:07 -0400 Subject: [PATCH 34/74] POLARIS: Another recharger fix --- code/game/machinery/rechargestation.dm | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index b1631718982..692e76bf5a4 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -115,7 +115,7 @@ H.adjustBrainLoss(-(rand(1,3))) // Also recharge their internal battery. - if(!isnull(H.internal_organs_by_name["cell"]) && H.nutrition < 450) + if(H.isSynthetic() && H.nutrition < 450) H.nutrition = min(H.nutrition+10, 450) cell.use(7000/450*10) @@ -264,17 +264,6 @@ else return -/obj/machinery/recharge_station/proc/hascell(var/mob/M) - if(isrobot(M)) - var/mob/living/silicon/robot/R = M - if(R.cell) - return 1 - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!isnull(H.internal_organs_by_name["cell"])) - return 1 - return 0 - /obj/machinery/recharge_station/proc/go_out() if(!occupant) return From acac33ca39439c32c23dfad4ec846ee26c54b3de Mon Sep 17 00:00:00 2001 From: Anewbe Date: Wed, 21 Mar 2018 19:12:14 -0500 Subject: [PATCH 35/74] Removes some problematic HIDEJUMPSUIT flags --- code/modules/clothing/suits/armor.dm | 7 +++---- code/modules/clothing/suits/jobs.dm | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index fcb3040f811..40ce8258afb 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -45,7 +45,6 @@ icon_state = "riot" item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat") armor = list(melee = 80, bullet = 10, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0) - flags_inv = HIDEJUMPSUIT siemens_coefficient = 0.5 /obj/item/clothing/suit/armor/riot/alt @@ -115,7 +114,7 @@ icon_state = "swatarmor" item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat") body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - flags_inv = HIDEJUMPSUIT|HIDETIE|HIDEHOLSTER + flags_inv = HIDETIE|HIDEHOLSTER slowdown = 1 armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 40, bio = 0, rad = 0) siemens_coefficient = 0.7 @@ -311,7 +310,7 @@ desc = "An armoured jacket with silver rank pips and livery." icon_state = "warden_jacket" body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS - flags_inv = HIDEJUMPSUIT|HIDETIE|HIDEHOLSTER + flags_inv = HIDETIE|HIDEHOLSTER /obj/item/clothing/suit/storage/vest/wardencoat/alt name = "Warden's jacket" @@ -332,7 +331,7 @@ desc = "A greatcoat enhanced with a special alloy for some protection and style." icon_state = "hos" body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS - flags_inv = HIDEJUMPSUIT|HIDETIE|HIDEHOLSTER + flags_inv = HIDETIE|HIDEHOLSTER //Jensen cosplay gear /obj/item/clothing/suit/storage/vest/hoscoat/jensen diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index aa2e95c3491..1d93fe9f25a 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -45,7 +45,7 @@ desc = "A long, flowing white robe. It looks comfortable, but not very warm." icon_state = "whiteout_robe" item_state_slots = list(slot_r_hand_str = "suit_white", slot_l_hand_str = "suit_white") - flags_inv = HIDEJUMPSUIT|HIDETIE|HIDEHOLSTER + flags_inv = HIDETIE|HIDEHOLSTER hoodtype = /obj/item/clothing/head/chaplain_hood/whiteout //Chaplain From 02aa2c126c0822f887d1e384dc46ba7602b00984 Mon Sep 17 00:00:00 2001 From: Drexian Date: Thu, 22 Mar 2018 03:39:16 +0300 Subject: [PATCH 36/74] Camera fix --- code/_helpers/icons.dm | 321 ++++++++++++++++++----------------------- 1 file changed, 142 insertions(+), 179 deletions(-) diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index da4385ef6ff..64460aa8895 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -634,211 +634,175 @@ as a single icon. Useful for when you want to manipulate an icon via the above a The _flatIcons list is a cache for generated icon files. */ -// Creates a single icon from a given /atom or /image. Only the first argument is required. -/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE) - // We start with a blank canvas, otherwise some icon procs crash silently - var/icon/flat = icon('icons/effects/effects.dmi', "nothing") // Final flattened icon - if(!A) - return flat - if(A.alpha <= 0) - return flat - var/noIcon = FALSE +proc // Creates a single icon from a given /atom or /image. Only the first argument is required. + getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0, picture_planes = list(PLANE_WORLD)) + // We start with a blank canvas, otherwise some icon procs crash silently + var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon + if(!A) + return flat + if(A.alpha <= 0) + return flat + var/noIcon = FALSE - if(start) - if(!defdir) - defdir = A.dir - if(!deficon) - deficon = A.icon - if(!defstate) - defstate = A.icon_state - if(!defblend) - defblend = A.blend_mode - - var/curicon - if(A.icon) - curicon = A.icon - else - curicon = deficon - - if(!curicon) - noIcon = TRUE // Do not render this object. - - var/curstate - if(A.icon_state) - curstate = A.icon_state - else - curstate = defstate - - if(!noIcon && !(curstate in icon_states(curicon))) - if("" in icon_states(curicon)) - curstate = "" + var/curicon + if(A.icon) + curicon = A.icon else + curicon = deficon + + if(!curicon) noIcon = TRUE // Do not render this object. - var/curdir - var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have - - //These should use the parent's direction (most likely) - if(!A.dir || A.dir == SOUTH) - curdir = defdir - else - curdir = A.dir + var/curstate + if(A.icon_state) + curstate = A.icon_state + else + curstate = defstate - //Let's check if the icon actually contains any diagonals, just skip if it's south to save (lot of) time - if(curdir != SOUTH) - var/icon/test_icon - var/directionals_exist = FALSE - var/list/dirs_to_check = cardinal - SOUTH - outer: - for(var/possible_dir in dirs_to_check) - test_icon = icon(curicon,curstate,possible_dir,frame=1) - for(var/x in 1 to world.icon_size) - for(var/y in 1 to world.icon_size) - if(!isnull(test_icon.GetPixel(x,y))) - directionals_exist = TRUE - break outer - if(!directionals_exist) - base_icon_dir = SOUTH - if(!base_icon_dir) - base_icon_dir = curdir + if(!noIcon && !(curstate in icon_states(curicon))) + if("" in icon_states(curicon)) + curstate = "" + else + noIcon = TRUE // Do not render this object. - var/curblend - if(A.blend_mode == BLEND_DEFAULT) - curblend = defblend - else - curblend = A.blend_mode + var/curdir + if(A.dir != 2 && !always_use_defdir) + curdir = A.dir + else + curdir = defdir - // Before processing overlays, make sure any pending overlays are applied - if (isloc(A)) - var/atom/aAtom = A - if(aAtom.flags & OVERLAY_QUEUED) - COMPILE_OVERLAYS(aAtom) + var/curblend + if(A.blend_mode == BLEND_DEFAULT) + curblend = defblend + else + curblend = A.blend_mode - // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed - var/list/layers = list() - var/image/copy - // Add the atom's icon itself, without pixel_x/y offsets. - if(!noIcon) - copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir) - copy.color = A.color - copy.alpha = A.alpha - copy.blend_mode = curblend - layers[copy] = A.layer + // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed + var/list/layers = list() + var/image/copy + // Add the atom's icon itself, without pixel_x/y offsets. + if(!noIcon) + copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=curdir) + copy.color = A.color + copy.alpha = A.alpha + copy.blend_mode = curblend + layers[copy] = A.layer + + // Loop through the underlays, then overlays, sorting them into the layers list + var/list/process = A.underlays // Current list being processed + var/pSet=0 // Which list is being processed: 0 = underlays, 1 = overlays + var/curIndex=1 // index of 'current' in list being processed + var/current // Current overlay being sorted + var/currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER) + var/compare // The overlay 'add' is being compared against + var/cmpIndex // The index in the layers list of 'compare' + while(TRUE) + if(curIndex<=process.len) + current = process[curIndex] + if(current) + var/currentPlane = current:plane + if (currentPlane != FLOAT_PLANE && !(currentPlane in picture_planes)) + curIndex++ + continue; + currentLayer = current:layer + if(currentLayer<0) // Special case for FLY_LAYER + if(currentLayer <= -1000) return flat + if(pSet == 0) // Underlay + currentLayer = A.layer+currentLayer/1000 + else // Overlay + currentLayer = A.layer+(1000+currentLayer)/1000 + + // Sort add into layers list + for(cmpIndex=1,cmpIndex<=layers.len,cmpIndex++) + compare = layers[cmpIndex] + if(currentLayer < layers[compare]) // Associated value is the calculated layer + layers.Insert(cmpIndex,current) + layers[current] = currentLayer + break + if(cmpIndex>layers.len) // Reached end of list without inserting + layers[current]=currentLayer // Place at end - // Loop through the underlays, then overlays, sorting them into the layers list - var/list/process = A.underlays // Current list being processed - var/pSet=0 // Which list is being processed: 0 = underlays, 1 = overlays - var/curIndex=1 // index of 'current' in list being processed - var/current // Current overlay being sorted - var/currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER) - var/compare // The overlay 'add' is being compared against - var/cmpIndex // The index in the layers list of 'compare' - while(TRUE) - if(curIndex<=process.len) - current = process[curIndex] - if(!current) - curIndex++ //Try the next layer - continue - var/image/I = current - if(I.plane != FLOAT_PLANE && I.plane != A.plane) curIndex++ - continue - currentLayer = I.layer - if(currentLayer<0) // Special case for FLOAT_LAYER - if(currentLayer <= -1000) - return flat - if(pSet == 0) // Underlay - currentLayer = A.layer+currentLayer/1000 - else // Overlay - currentLayer = A.layer+(1000+currentLayer)/1000 - - // Sort add into layers list - for(cmpIndex=1,cmpIndex<=layers.len,cmpIndex++) - compare = layers[cmpIndex] - if(currentLayer < layers[compare]) // Associated value is the calculated layer - layers.Insert(cmpIndex,current) - layers[current] = currentLayer - break - if(cmpIndex>layers.len) // Reached end of list without inserting - layers[current]=currentLayer // Place at end - - curIndex++ - - if(curIndex>process.len) - if(pSet == 0) // Switch to overlays + else if(pSet == 0) // Switch to overlays curIndex = 1 pSet = 1 process = A.overlays else // All done break - var/icon/add // Icon of overlay being added + var/icon/add // Icon of overlay being added - // Current dimensions of flattened icon - var/flatX1=1 - var/flatX2=flat.Width() - var/flatY1=1 - var/flatY2=flat.Height() - // Dimensions of overlay being added - var/addX1 - var/addX2 - var/addY1 - var/addY2 + // Current dimensions of flattened icon + var/{flatX1=1;flatX2=flat.Width();flatY1=1;flatY2=flat.Height()} + // Dimensions of overlay being added + var/{addX1;addX2;addY1;addY2} - for(var/V in layers) - var/image/I = V - if(I.alpha == 0) - continue + for(var/I in layers) - if(I == copy) // 'I' is an /image based on the object being flattened. - curblend = BLEND_OVERLAY - add = icon(I.icon, I.icon_state, base_icon_dir) - else // 'I' is an appearance object. - add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, FALSE, no_anim) + if(I:alpha == 0) + continue - // Find the new dimensions of the flat icon to fit the added overlay - addX1 = min(flatX1, I.pixel_x+1) - addX2 = max(flatX2, I.pixel_x+add.Width()) - addY1 = min(flatY1, I.pixel_y+1) - addY2 = max(flatY2, I.pixel_y+add.Height()) + if(I == copy) // 'I' is an /image based on the object being flattened. + curblend = BLEND_OVERLAY + add = icon(I:icon, I:icon_state, I:dir) + // This checks for a silent failure mode of the icon routine. If the requested dir + // doesn't exist in this icon state it returns a 32x32 icon with 0 alpha. + if (I:dir != SOUTH && add.Width() == 32 && add.Height() == 32) + // Check every pixel for blank (computationally expensive, but the process is limited + // by the amount of film on the station, only happens when we hit something that's + // turned, and bails at the very first pixel it sees. + var/blankpixel; + for(var/y;y<=32;y++) + for(var/x;x<32;x++) + blankpixel = isnull(add.GetPixel(x,y)) + if(!blankpixel) + break + if(!blankpixel) + break + // If we ALWAYS returned a null (which happens when GetPixel encounters something with alpha 0) + if (blankpixel) + // Pull the default direction. + add = icon(I:icon, I:icon_state) + else // 'I' is an appearance object. + add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, picture_planes = picture_planes) - if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2) - // Resize the flattened icon so the new icon fits - flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1) - flatX1=addX1;flatX2=addX2 - flatY1=addY1;flatY2=addY2 + // Find the new dimensions of the flat icon to fit the added overlay + addX1 = min(flatX1, I:pixel_x+1) + addX2 = max(flatX2, I:pixel_x+add.Width()) + addY1 = min(flatY1, I:pixel_y+1) + addY2 = max(flatY2, I:pixel_y+add.Height()) - // Blend the overlay into the flattened icon - flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1) + if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2) + // Resize the flattened icon so the new icon fits + flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1) + flatX1=addX1;flatX2=addX2 + flatY1=addY1;flatY2=addY2 - if(A.color) - flat.Blend(A.color, ICON_MULTIPLY) - if(A.alpha < 255) - flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) + // Blend the overlay into the flattened icon + flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1) + + if(A.color) + flat.Blend(A.color, ICON_MULTIPLY) + if(A.alpha < 255) + flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) - if(no_anim) - //Clean up repeated frames - var/icon/cleaned = new /icon() - cleaned.Insert(flat, "", SOUTH, 1, 0) - return cleaned - else return icon(flat, "", SOUTH) -/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N - var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. - for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. - if(I:layer>A.layer) continue//If layer is greater than what we need, skip it. - var/icon/image_overlay = new(I:icon,I:icon_state)//Blend only works with icon objects. - //Also, icons cannot directly set icon_state. Slower than changing variables but whatever. - alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. - return alpha_mask//And now return the mask. + getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N + var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. + for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. + if(I:layer>A.layer) continue//If layer is greater than what we need, skip it. + var/icon/image_overlay = new(I:icon,I:icon_state)//Blend only works with icon objects. + //Also, icons cannot directly set icon_state. Slower than changing variables but whatever. + alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. + return alpha_mask//And now return the mask. //getFlatIcon but generates an icon that can face ALL four directions. The only four. /proc/getCompoundIcon(atom/A) - var/icon/north = getFlatIcon(A,defdir=NORTH) - var/icon/south = getFlatIcon(A,defdir=SOUTH) - var/icon/east = getFlatIcon(A,defdir=EAST) - var/icon/west = getFlatIcon(A,defdir=WEST) + var/icon/north = getFlatIcon(A,defdir=NORTH,always_use_defdir=1) + var/icon/south = getFlatIcon(A,defdir=SOUTH,always_use_defdir=1) + var/icon/east = getFlatIcon(A,defdir=EAST,always_use_defdir=1) + var/icon/west = getFlatIcon(A,defdir=WEST,always_use_defdir=1) //Starts with a blank icon because of byond bugs. var/icon/full = icon('icons/effects/effects.dmi', "icon_state"="nothing") @@ -854,7 +818,7 @@ The _flatIcons list is a cache for generated icon files. return full /proc/downloadImage(atom/A, dir) - var/icon/this_icon = getFlatIcon(A,defdir=dir) + var/icon/this_icon = getFlatIcon(A,defdir=dir||A.dir,always_use_defdir=1) usr << ftp(this_icon,"[A.name].png") @@ -922,8 +886,7 @@ proc/sort_atoms_by_layer(var/list/atoms) /proc/gen_hud_image(var/file, var/person, var/state, var/plane) var/image/img = image(file, person, state) img.plane = plane //Thanks Byond. - img.layer = MOB_LAYER-0.2 - img.appearance_flags = APPEARANCE_UI + img.appearance_flags = APPEARANCE_UI|KEEP_APART return img /** From f1c9193797378b5897e1fe2b8f331c82a2fd1b44 Mon Sep 17 00:00:00 2001 From: Drexian Date: Thu, 22 Mar 2018 03:42:09 +0300 Subject: [PATCH 37/74] adds statue --- code/modules/mob/living/carbon/human/human.dm | 1 + code/modules/mob/living/living.dm | 6 +- code/modules/mob/living/silicon/silicon.dm | 3 + .../mob/living/simple_animal/aliens/statue.dm | 315 ++++++++++++++++++ code/modules/paperwork/photography.dm | 23 +- polaris.dme | 2 + 6 files changed, 348 insertions(+), 2 deletions(-) create mode 100644 code/modules/mob/living/simple_animal/aliens/statue.dm diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b3748ee25c4..315d020dbec 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1562,3 +1562,4 @@ status_flags &= ~HIDING //No hiding for you. Mob layer should be updated naturally, but it actually isn't. else layer = HIDING_LAYER + diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9a7ba9fb0f9..99a86bc9c51 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1015,7 +1015,7 @@ default behaviour is: if(lying != lying_prev) lying_prev = lying update_transform() - + return canmove // Adds overlays for specific modifiers. @@ -1201,3 +1201,7 @@ default behaviour is: /mob/living/proc/make_hud_overlays() return + + +/mob/living/proc/has_vision() + return !(eye_blind || (disabilities & BLIND) || stat || blinded) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 0d88e0c96ff..a142206cf66 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -418,3 +418,6 @@ ghostize(0) qdel(src) + +/mob/living/silicon/has_vision() + return 0 //NOT REAL EYES diff --git a/code/modules/mob/living/simple_animal/aliens/statue.dm b/code/modules/mob/living/simple_animal/aliens/statue.dm new file mode 100644 index 00000000000..cdcb92e23ef --- /dev/null +++ b/code/modules/mob/living/simple_animal/aliens/statue.dm @@ -0,0 +1,315 @@ +// A mob which only moves when it isn't being watched by living beings. +//SCP - 173 hype +//Horrible shitcoding and stolen code adaptations below. You have been warned. + +/mob/living/simple_animal/hostile/statue + name = "statue" // matches the name of the statue with the flesh-to-stone spell + desc = "An incredibly lifelike marble carving. Its eyes seems to follow you..." // same as an ordinary statue with the added "eye following you" description + icon = 'icons/obj/statue.dmi' + icon_state = "human_male" + icon_living = "human_male" + icon_dead = "human_male" + intelligence_level = SA_HUMANOID + var/annoyance = 0 //stop fucking staring you creep + var/last_response = 0 + faction = "statue" + mob_size = MOB_HUGE + response_help = "touches" + response_disarm = "pushes" + environment_smash = 2 + can_be_antagged = 1 + speed = -1 + maxHealth = 50000 + health = 50000 +// investigates = 1 + + + harm_intent_damage = 35 + melee_damage_lower = 30 + melee_damage_upper = 45 + attacktext = "clawed" + attack_sound = 'sound/hallucinations/growl1.ogg' + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + maxbodytemp = 9000 + run_at_them = 0 + + + move_to_delay = 0 // Very fast + + animate_movement = NO_STEPS // Do not animate movement, you jump around as you're a scary statue. + + see_in_dark = 13 + view_range = 35 //So it can run at the victim when out of the view +// supernatural = 1 +/* aggro_vision_range = 12 + idle_vision_range = 12 +*/ + melee_miss_chance = 0 + + + see_invisible = SEE_INVISIBLE_NOLIGHTING + sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS + anchored = 1 + status_flags = GODMODE // Cannot push also + var/last_hit = 0 + var/cannot_be_seen = 1 + var/mob/living/creator = null + mob_swap_flags = null + +// No movement while seen code. + +/mob/living/simple_animal/hostile/statue/New(loc, var/mob/living/creator) + ..() + last_response = world.time + // Give spells + add_spell(new/spell/aoe_turf/flicker_lights) + add_spell(new/spell/aoe_turf/blindness) + add_spell(new/spell/aoe_turf/shatter) + + + // Set creator + if(creator) + src.creator = creator + +/mob/living/simple_animal/hostile/statue/DestroySurroundings() + if(can_be_seen(get_turf(loc))) + if(client) + to_chat(src, "You cannot move, there are eyes on you!") + return 0 + return ..() + +/mob/living/simple_animal/hostile/statue/Move(turf/NewLoc) + if(can_be_seen(NewLoc)) + if(client) + to_chat(src, "You cannot move, there are eyes on you!") + return 0 + return ..() + +/mob/living/simple_animal/hostile/statue/Life() + ..() + handleAnnoyance() + if ((annoyance - 2) > 0) + annoyance -= 2 + if(target_mob) + if((annoyance + 5) < 800) + annoyance += 5 + +/mob/living/simple_animal/hostile/statue/handle_stance() + if(!..()) + return + if(target_mob) // If we have a target and we're AI controlled + var/mob/watching = can_be_seen() + // If they're not our target + if(watching && watching != target_mob) + // This one is closer. + if(get_dist(watching, src) > get_dist(target_mob, src)) + LoseTarget() + target_mob = watching + + +/mob/living/simple_animal/hostile/statue/proc/handleAnnoyance() + if(last_response + 3 SECONDS < world.time) //so it won't blind people 24/7 + return + var/turf/T = get_turf(loc) + if (annoyance > 60) + AI_blind() + annoyance -= 25 + if (prob(50)) + if(T.get_lumcount() * 10 > 1.5) + AI_flash() + annoyance -= 35 + last_response = world.time + return + + +/mob/living/simple_animal/hostile/statue/proc/AI_blind() + for(var/mob/living/L in range(7, src)) + if(L == src) + continue + if (prob(75)) + if(istype(L , /mob/living/carbon/human)) + var/mob/living/carbon/human/H = L + if (H.species == "Diona" || H.species == "Promethean")// can't blink and organic + return + to_chat(L, "Your eyes feel very heavy.") + L.Blind(5) + return + +/mob/living/simple_animal/hostile/statue/proc/AI_flash() + if (prob(60)) + visible_message("The statue slowly points at the light.") + for(var/obj/machinery/light/L in range(10, src)) + L.flicker() + return + + +/mob/living/simple_animal/hostile/statue/proc/AI_mirrorshmash() + for(var/obj/structure/mirror/M in range(10, src)) + if ((!M.shattered )||(!M.glass)) + visible_message("The mirror shatters!") + M.shatter() + return + + + +/mob/living/simple_animal/hostile/statue/AttackTarget() + if(can_be_seen(get_turf(loc))) + if(client) + to_chat(src, "You cannot attack, there are eyes on you!") + return + else if(prob(80)) + spawn(4) + ..() + + + +/mob/living/simple_animal/hostile/statue/face_atom() + if(!can_be_seen(get_turf(loc))) + ..() + +/mob/living/simple_animal/hostile/statue/proc/can_be_seen(turf/destination) + if(!cannot_be_seen) + return null + // Check for darkness + var/turf/T = get_turf(loc) + if(T && destination && T.lighting_overlay) + if(T.get_lumcount() * 10 < 1 && destination.get_lumcount() * 10 < 1) // No one can see us in the darkness, right? + return null + if(T == destination) + destination = null + + // We aren't in darkness, loop for viewers. + var/list/check_list = list(src) + if(destination) + check_list += destination + + // This loop will, at most, loop twice. + for(var/atom/check in check_list) + for(var/mob/living/M in viewers(world.view + 1, check) - src) + if(!(M.sdisabilities & BLIND) || !(M.blinded)) + if(M.has_vision() && !M.isSynthetic()) + return M + for(var/obj/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you + if(M.occupant && M.occupant.client) + if(M.occupant.has_vision() && !M.occupant.isSynthetic()) + return M.occupant + for(var/obj/structure/mirror/M in view(7, check)) //Weeping angels hate mirrors. Probably because they're ugly af + if ((!M.shattered )||(!M.glass)) + annoyance += 2 + if ((annoyance > 200) && (ai_inactive == 0)) + AI_mirrorshmash() + annoyance -= 200 + return src //if it sees the mirror, it sees itself, right? + return null + +// Cannot talk + +/mob/living/simple_animal/hostile/statue/say() + return 0 + +// Turn to dust when gibbed + +/mob/living/simple_animal/hostile/statue/gib() + dust() + + +// Stop attacking clientless mobs + +/mob/living/simple_animal/hostile/statue/proc/CanAttack(atom/the_target) //ignore clientless mobs + if(isliving(the_target)) + var/mob/living/L = the_target + if(!L.client && !L.ckey) + return 0 + return ..() + +// Statue powers + +// Flicker lights +/spell/aoe_turf/flicker_lights + name = "Flicker Lights" + desc = "You will trigger a large amount of lights around you to flicker." + spell_flags = 0 + charge_max = 400 + range = 14 + +/spell/aoe_turf/flicker_lights/cast(list/targets, mob/user = usr) + for(var/turf/T in targets) + for(var/obj/machinery/light/L in T) + L.flicker() + return + +//Blind AOE +/spell/aoe_turf/blindness + name = "Blindness" + desc = "Your prey will be momentarily blind for you to advance on them." + + message = "You glare your eyes." + charge_max = 250 + spell_flags = 0 + range = 10 + +/spell/aoe_turf/blindness/cast(list/targets, mob/user = usr) + for(var/mob/living/L in living_mob_list) + if(L == user) + continue + var/turf/T = get_turf(L.loc) + if(T && T in targets) + L.Blind(7) + return + + +/spell/aoe_turf/shatter + name = "Shatter mirrors!" + desc = "That handsome devil has to wait. You have people to make into corpses." + + message = "You glare your eyes." + charge_max = 2000 + silenced = 500 + spell_flags = 0 + range = 10 + + + + +/spell/aoe_turf/shatter/cast(list/targets, mob/user = usr) + for(var/obj/structure/mirror/M in range(10, src)) + if ((!M.shattered )||(!M.glass)) + M.shatter() + return + + + +/mob/living/simple_animal/hostile/statue/verb/toggle_darkness() + set name = "Toggle Darkness" + set desc = "You ARE the darkness." + set category = "Abilities" + seedarkness = !seedarkness + plane_holder.set_vis(VIS_FULLBRIGHT, !seedarkness) + to_chat(src,"You [seedarkness ? "now" : "no longer"] see darkness.") + + + +/mob/living/simple_animal/hostile/statue/restrained() + . = ..() + if(can_be_seen(loc)) + return 1 + + + +/mob/living/simple_animal/hostile/statue/ListTargets() + . = ..() + + for(var/mob/living/V in mobs_in_xray_view(20, src)) + . += V + + + return . diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index c8b78cfd654..9b0ca19ed56 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -33,11 +33,14 @@ var/global/photo_count = 0 var/icon/img //Big photo image var/scribble //Scribble on the back. var/icon/tiny + var/cursed = 0 var/photo_size = 3 /obj/item/weapon/photo/New() id = photo_count++ + + /obj/item/weapon/photo/attack_self(mob/user as mob) user.examinate(src) @@ -233,6 +236,11 @@ var/global/photo_count = 0 mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. " else mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]." + + for(var/mob/living/simple_animal/hostile/statue/S in the_turf) + if(S) + mob_detail += "You can see a [S] on the photo. Its stare makes you feel uneasy." //"That which holds the image of an angel, becomes itself an angel." + return mob_detail /obj/item/device/camera/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) @@ -274,7 +282,16 @@ var/global/photo_count = 0 y_c-- x_c = x_c - size + + + var/obj/item/weapon/photo/p = createpicture(target, user, turfs, mobs, flag) + if(findtext(mobs, "Its stare makes you feel uneasy")) + p.cursed = 1 + visible_message("Something starts to slowly manifest from the picture!") + spawn(150) + new /mob/living/simple_animal/hostile/statue(usr.loc) + printpicture(user, p) /obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, mobs, flag) @@ -298,7 +315,6 @@ var/global/photo_count = 0 p.pixel_x = rand(-10, 10) p.pixel_y = rand(-10, 10) p.photo_size = size - return p /obj/item/device/camera/proc/printpicture(mob/user, obj/item/weapon/photo/p) @@ -318,6 +334,11 @@ var/global/photo_count = 0 p.pixel_y = pixel_y p.photo_size = photo_size p.scribble = scribble + p.cursed = cursed + if(p.cursed) + visible_message("Something starts to slowly manifest from the picture!") + spawn(150) + new /mob/living/simple_animal/hostile/statue(usr.loc) if(copy_id) p.id = id diff --git a/polaris.dme b/polaris.dme index 0bb899cea27..b3db30781b3 100644 --- a/polaris.dme +++ b/polaris.dme @@ -1877,6 +1877,7 @@ #include "code\modules\mob\living\simple_animal\aliens\hivebot.dm" #include "code\modules\mob\living\simple_animal\aliens\mimic.dm" #include "code\modules\mob\living\simple_animal\aliens\shade.dm" +#include "code\modules\mob\living\simple_animal\aliens\statue.dm" #include "code\modules\mob\living\simple_animal\animals\bat.dm" #include "code\modules\mob\living\simple_animal\animals\bear.dm" #include "code\modules\mob\living\simple_animal\animals\carp.dm" @@ -2428,6 +2429,7 @@ #include "code\ZAS\Zone.dm" #include "interface\interface.dm" #include "interface\skin.dmf" +#include "maps\northern_star\northern_star.dm" #include "maps\southern_cross\southern_cross.dm" #include "maps\submaps\_readme.dm" #include "maps\submaps\space_submaps\space.dm" From a95eb8cebd7a17db8789154e7468bb1332df22e2 Mon Sep 17 00:00:00 2001 From: Drexian Date: Thu, 22 Mar 2018 03:42:09 +0300 Subject: [PATCH 38/74] adds statue --- code/modules/mob/living/carbon/human/human.dm | 1 + code/modules/mob/living/living.dm | 6 +- code/modules/mob/living/silicon/silicon.dm | 3 + .../mob/living/simple_animal/aliens/statue.dm | 315 ++++++++++++++++++ code/modules/paperwork/photography.dm | 23 +- polaris.dme | 2 + 6 files changed, 348 insertions(+), 2 deletions(-) create mode 100644 code/modules/mob/living/simple_animal/aliens/statue.dm diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b3748ee25c4..315d020dbec 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1562,3 +1562,4 @@ status_flags &= ~HIDING //No hiding for you. Mob layer should be updated naturally, but it actually isn't. else layer = HIDING_LAYER + diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9a7ba9fb0f9..99a86bc9c51 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1015,7 +1015,7 @@ default behaviour is: if(lying != lying_prev) lying_prev = lying update_transform() - + return canmove // Adds overlays for specific modifiers. @@ -1201,3 +1201,7 @@ default behaviour is: /mob/living/proc/make_hud_overlays() return + + +/mob/living/proc/has_vision() + return !(eye_blind || (disabilities & BLIND) || stat || blinded) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 0d88e0c96ff..a142206cf66 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -418,3 +418,6 @@ ghostize(0) qdel(src) + +/mob/living/silicon/has_vision() + return 0 //NOT REAL EYES diff --git a/code/modules/mob/living/simple_animal/aliens/statue.dm b/code/modules/mob/living/simple_animal/aliens/statue.dm new file mode 100644 index 00000000000..cdcb92e23ef --- /dev/null +++ b/code/modules/mob/living/simple_animal/aliens/statue.dm @@ -0,0 +1,315 @@ +// A mob which only moves when it isn't being watched by living beings. +//SCP - 173 hype +//Horrible shitcoding and stolen code adaptations below. You have been warned. + +/mob/living/simple_animal/hostile/statue + name = "statue" // matches the name of the statue with the flesh-to-stone spell + desc = "An incredibly lifelike marble carving. Its eyes seems to follow you..." // same as an ordinary statue with the added "eye following you" description + icon = 'icons/obj/statue.dmi' + icon_state = "human_male" + icon_living = "human_male" + icon_dead = "human_male" + intelligence_level = SA_HUMANOID + var/annoyance = 0 //stop fucking staring you creep + var/last_response = 0 + faction = "statue" + mob_size = MOB_HUGE + response_help = "touches" + response_disarm = "pushes" + environment_smash = 2 + can_be_antagged = 1 + speed = -1 + maxHealth = 50000 + health = 50000 +// investigates = 1 + + + harm_intent_damage = 35 + melee_damage_lower = 30 + melee_damage_upper = 45 + attacktext = "clawed" + attack_sound = 'sound/hallucinations/growl1.ogg' + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + maxbodytemp = 9000 + run_at_them = 0 + + + move_to_delay = 0 // Very fast + + animate_movement = NO_STEPS // Do not animate movement, you jump around as you're a scary statue. + + see_in_dark = 13 + view_range = 35 //So it can run at the victim when out of the view +// supernatural = 1 +/* aggro_vision_range = 12 + idle_vision_range = 12 +*/ + melee_miss_chance = 0 + + + see_invisible = SEE_INVISIBLE_NOLIGHTING + sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS + anchored = 1 + status_flags = GODMODE // Cannot push also + var/last_hit = 0 + var/cannot_be_seen = 1 + var/mob/living/creator = null + mob_swap_flags = null + +// No movement while seen code. + +/mob/living/simple_animal/hostile/statue/New(loc, var/mob/living/creator) + ..() + last_response = world.time + // Give spells + add_spell(new/spell/aoe_turf/flicker_lights) + add_spell(new/spell/aoe_turf/blindness) + add_spell(new/spell/aoe_turf/shatter) + + + // Set creator + if(creator) + src.creator = creator + +/mob/living/simple_animal/hostile/statue/DestroySurroundings() + if(can_be_seen(get_turf(loc))) + if(client) + to_chat(src, "You cannot move, there are eyes on you!") + return 0 + return ..() + +/mob/living/simple_animal/hostile/statue/Move(turf/NewLoc) + if(can_be_seen(NewLoc)) + if(client) + to_chat(src, "You cannot move, there are eyes on you!") + return 0 + return ..() + +/mob/living/simple_animal/hostile/statue/Life() + ..() + handleAnnoyance() + if ((annoyance - 2) > 0) + annoyance -= 2 + if(target_mob) + if((annoyance + 5) < 800) + annoyance += 5 + +/mob/living/simple_animal/hostile/statue/handle_stance() + if(!..()) + return + if(target_mob) // If we have a target and we're AI controlled + var/mob/watching = can_be_seen() + // If they're not our target + if(watching && watching != target_mob) + // This one is closer. + if(get_dist(watching, src) > get_dist(target_mob, src)) + LoseTarget() + target_mob = watching + + +/mob/living/simple_animal/hostile/statue/proc/handleAnnoyance() + if(last_response + 3 SECONDS < world.time) //so it won't blind people 24/7 + return + var/turf/T = get_turf(loc) + if (annoyance > 60) + AI_blind() + annoyance -= 25 + if (prob(50)) + if(T.get_lumcount() * 10 > 1.5) + AI_flash() + annoyance -= 35 + last_response = world.time + return + + +/mob/living/simple_animal/hostile/statue/proc/AI_blind() + for(var/mob/living/L in range(7, src)) + if(L == src) + continue + if (prob(75)) + if(istype(L , /mob/living/carbon/human)) + var/mob/living/carbon/human/H = L + if (H.species == "Diona" || H.species == "Promethean")// can't blink and organic + return + to_chat(L, "Your eyes feel very heavy.") + L.Blind(5) + return + +/mob/living/simple_animal/hostile/statue/proc/AI_flash() + if (prob(60)) + visible_message("The statue slowly points at the light.") + for(var/obj/machinery/light/L in range(10, src)) + L.flicker() + return + + +/mob/living/simple_animal/hostile/statue/proc/AI_mirrorshmash() + for(var/obj/structure/mirror/M in range(10, src)) + if ((!M.shattered )||(!M.glass)) + visible_message("The mirror shatters!") + M.shatter() + return + + + +/mob/living/simple_animal/hostile/statue/AttackTarget() + if(can_be_seen(get_turf(loc))) + if(client) + to_chat(src, "You cannot attack, there are eyes on you!") + return + else if(prob(80)) + spawn(4) + ..() + + + +/mob/living/simple_animal/hostile/statue/face_atom() + if(!can_be_seen(get_turf(loc))) + ..() + +/mob/living/simple_animal/hostile/statue/proc/can_be_seen(turf/destination) + if(!cannot_be_seen) + return null + // Check for darkness + var/turf/T = get_turf(loc) + if(T && destination && T.lighting_overlay) + if(T.get_lumcount() * 10 < 1 && destination.get_lumcount() * 10 < 1) // No one can see us in the darkness, right? + return null + if(T == destination) + destination = null + + // We aren't in darkness, loop for viewers. + var/list/check_list = list(src) + if(destination) + check_list += destination + + // This loop will, at most, loop twice. + for(var/atom/check in check_list) + for(var/mob/living/M in viewers(world.view + 1, check) - src) + if(!(M.sdisabilities & BLIND) || !(M.blinded)) + if(M.has_vision() && !M.isSynthetic()) + return M + for(var/obj/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you + if(M.occupant && M.occupant.client) + if(M.occupant.has_vision() && !M.occupant.isSynthetic()) + return M.occupant + for(var/obj/structure/mirror/M in view(7, check)) //Weeping angels hate mirrors. Probably because they're ugly af + if ((!M.shattered )||(!M.glass)) + annoyance += 2 + if ((annoyance > 200) && (ai_inactive == 0)) + AI_mirrorshmash() + annoyance -= 200 + return src //if it sees the mirror, it sees itself, right? + return null + +// Cannot talk + +/mob/living/simple_animal/hostile/statue/say() + return 0 + +// Turn to dust when gibbed + +/mob/living/simple_animal/hostile/statue/gib() + dust() + + +// Stop attacking clientless mobs + +/mob/living/simple_animal/hostile/statue/proc/CanAttack(atom/the_target) //ignore clientless mobs + if(isliving(the_target)) + var/mob/living/L = the_target + if(!L.client && !L.ckey) + return 0 + return ..() + +// Statue powers + +// Flicker lights +/spell/aoe_turf/flicker_lights + name = "Flicker Lights" + desc = "You will trigger a large amount of lights around you to flicker." + spell_flags = 0 + charge_max = 400 + range = 14 + +/spell/aoe_turf/flicker_lights/cast(list/targets, mob/user = usr) + for(var/turf/T in targets) + for(var/obj/machinery/light/L in T) + L.flicker() + return + +//Blind AOE +/spell/aoe_turf/blindness + name = "Blindness" + desc = "Your prey will be momentarily blind for you to advance on them." + + message = "You glare your eyes." + charge_max = 250 + spell_flags = 0 + range = 10 + +/spell/aoe_turf/blindness/cast(list/targets, mob/user = usr) + for(var/mob/living/L in living_mob_list) + if(L == user) + continue + var/turf/T = get_turf(L.loc) + if(T && T in targets) + L.Blind(7) + return + + +/spell/aoe_turf/shatter + name = "Shatter mirrors!" + desc = "That handsome devil has to wait. You have people to make into corpses." + + message = "You glare your eyes." + charge_max = 2000 + silenced = 500 + spell_flags = 0 + range = 10 + + + + +/spell/aoe_turf/shatter/cast(list/targets, mob/user = usr) + for(var/obj/structure/mirror/M in range(10, src)) + if ((!M.shattered )||(!M.glass)) + M.shatter() + return + + + +/mob/living/simple_animal/hostile/statue/verb/toggle_darkness() + set name = "Toggle Darkness" + set desc = "You ARE the darkness." + set category = "Abilities" + seedarkness = !seedarkness + plane_holder.set_vis(VIS_FULLBRIGHT, !seedarkness) + to_chat(src,"You [seedarkness ? "now" : "no longer"] see darkness.") + + + +/mob/living/simple_animal/hostile/statue/restrained() + . = ..() + if(can_be_seen(loc)) + return 1 + + + +/mob/living/simple_animal/hostile/statue/ListTargets() + . = ..() + + for(var/mob/living/V in mobs_in_xray_view(20, src)) + . += V + + + return . diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index c8b78cfd654..9b0ca19ed56 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -33,11 +33,14 @@ var/global/photo_count = 0 var/icon/img //Big photo image var/scribble //Scribble on the back. var/icon/tiny + var/cursed = 0 var/photo_size = 3 /obj/item/weapon/photo/New() id = photo_count++ + + /obj/item/weapon/photo/attack_self(mob/user as mob) user.examinate(src) @@ -233,6 +236,11 @@ var/global/photo_count = 0 mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. " else mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]." + + for(var/mob/living/simple_animal/hostile/statue/S in the_turf) + if(S) + mob_detail += "You can see a [S] on the photo. Its stare makes you feel uneasy." //"That which holds the image of an angel, becomes itself an angel." + return mob_detail /obj/item/device/camera/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) @@ -274,7 +282,16 @@ var/global/photo_count = 0 y_c-- x_c = x_c - size + + + var/obj/item/weapon/photo/p = createpicture(target, user, turfs, mobs, flag) + if(findtext(mobs, "Its stare makes you feel uneasy")) + p.cursed = 1 + visible_message("Something starts to slowly manifest from the picture!") + spawn(150) + new /mob/living/simple_animal/hostile/statue(usr.loc) + printpicture(user, p) /obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, mobs, flag) @@ -298,7 +315,6 @@ var/global/photo_count = 0 p.pixel_x = rand(-10, 10) p.pixel_y = rand(-10, 10) p.photo_size = size - return p /obj/item/device/camera/proc/printpicture(mob/user, obj/item/weapon/photo/p) @@ -318,6 +334,11 @@ var/global/photo_count = 0 p.pixel_y = pixel_y p.photo_size = photo_size p.scribble = scribble + p.cursed = cursed + if(p.cursed) + visible_message("Something starts to slowly manifest from the picture!") + spawn(150) + new /mob/living/simple_animal/hostile/statue(usr.loc) if(copy_id) p.id = id diff --git a/polaris.dme b/polaris.dme index 0bb899cea27..b3db30781b3 100644 --- a/polaris.dme +++ b/polaris.dme @@ -1877,6 +1877,7 @@ #include "code\modules\mob\living\simple_animal\aliens\hivebot.dm" #include "code\modules\mob\living\simple_animal\aliens\mimic.dm" #include "code\modules\mob\living\simple_animal\aliens\shade.dm" +#include "code\modules\mob\living\simple_animal\aliens\statue.dm" #include "code\modules\mob\living\simple_animal\animals\bat.dm" #include "code\modules\mob\living\simple_animal\animals\bear.dm" #include "code\modules\mob\living\simple_animal\animals\carp.dm" @@ -2428,6 +2429,7 @@ #include "code\ZAS\Zone.dm" #include "interface\interface.dm" #include "interface\skin.dmf" +#include "maps\northern_star\northern_star.dm" #include "maps\southern_cross\southern_cross.dm" #include "maps\submaps\_readme.dm" #include "maps\submaps\space_submaps\space.dm" From 4ef959ebc12edb277d32f9607c2de55fdb6ff5b0 Mon Sep 17 00:00:00 2001 From: Drexian Date: Thu, 22 Mar 2018 03:53:29 +0300 Subject: [PATCH 39/74] Revert "adds statue" This reverts commit f1c9193797378b5897e1fe2b8f331c82a2fd1b44. --- code/modules/mob/living/carbon/human/human.dm | 1 - code/modules/mob/living/living.dm | 6 +- code/modules/mob/living/silicon/silicon.dm | 3 - .../mob/living/simple_animal/aliens/statue.dm | 315 ------------------ code/modules/paperwork/photography.dm | 23 +- polaris.dme | 2 - 6 files changed, 2 insertions(+), 348 deletions(-) delete mode 100644 code/modules/mob/living/simple_animal/aliens/statue.dm diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 315d020dbec..b3748ee25c4 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1562,4 +1562,3 @@ status_flags &= ~HIDING //No hiding for you. Mob layer should be updated naturally, but it actually isn't. else layer = HIDING_LAYER - diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 99a86bc9c51..9a7ba9fb0f9 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1015,7 +1015,7 @@ default behaviour is: if(lying != lying_prev) lying_prev = lying update_transform() - + return canmove // Adds overlays for specific modifiers. @@ -1201,7 +1201,3 @@ default behaviour is: /mob/living/proc/make_hud_overlays() return - - -/mob/living/proc/has_vision() - return !(eye_blind || (disabilities & BLIND) || stat || blinded) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index a142206cf66..0d88e0c96ff 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -418,6 +418,3 @@ ghostize(0) qdel(src) - -/mob/living/silicon/has_vision() - return 0 //NOT REAL EYES diff --git a/code/modules/mob/living/simple_animal/aliens/statue.dm b/code/modules/mob/living/simple_animal/aliens/statue.dm deleted file mode 100644 index cdcb92e23ef..00000000000 --- a/code/modules/mob/living/simple_animal/aliens/statue.dm +++ /dev/null @@ -1,315 +0,0 @@ -// A mob which only moves when it isn't being watched by living beings. -//SCP - 173 hype -//Horrible shitcoding and stolen code adaptations below. You have been warned. - -/mob/living/simple_animal/hostile/statue - name = "statue" // matches the name of the statue with the flesh-to-stone spell - desc = "An incredibly lifelike marble carving. Its eyes seems to follow you..." // same as an ordinary statue with the added "eye following you" description - icon = 'icons/obj/statue.dmi' - icon_state = "human_male" - icon_living = "human_male" - icon_dead = "human_male" - intelligence_level = SA_HUMANOID - var/annoyance = 0 //stop fucking staring you creep - var/last_response = 0 - faction = "statue" - mob_size = MOB_HUGE - response_help = "touches" - response_disarm = "pushes" - environment_smash = 2 - can_be_antagged = 1 - speed = -1 - maxHealth = 50000 - health = 50000 -// investigates = 1 - - - harm_intent_damage = 35 - melee_damage_lower = 30 - melee_damage_upper = 45 - attacktext = "clawed" - attack_sound = 'sound/hallucinations/growl1.ogg' - - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - minbodytemp = 0 - maxbodytemp = 9000 - run_at_them = 0 - - - move_to_delay = 0 // Very fast - - animate_movement = NO_STEPS // Do not animate movement, you jump around as you're a scary statue. - - see_in_dark = 13 - view_range = 35 //So it can run at the victim when out of the view -// supernatural = 1 -/* aggro_vision_range = 12 - idle_vision_range = 12 -*/ - melee_miss_chance = 0 - - - see_invisible = SEE_INVISIBLE_NOLIGHTING - sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS - anchored = 1 - status_flags = GODMODE // Cannot push also - var/last_hit = 0 - var/cannot_be_seen = 1 - var/mob/living/creator = null - mob_swap_flags = null - -// No movement while seen code. - -/mob/living/simple_animal/hostile/statue/New(loc, var/mob/living/creator) - ..() - last_response = world.time - // Give spells - add_spell(new/spell/aoe_turf/flicker_lights) - add_spell(new/spell/aoe_turf/blindness) - add_spell(new/spell/aoe_turf/shatter) - - - // Set creator - if(creator) - src.creator = creator - -/mob/living/simple_animal/hostile/statue/DestroySurroundings() - if(can_be_seen(get_turf(loc))) - if(client) - to_chat(src, "You cannot move, there are eyes on you!") - return 0 - return ..() - -/mob/living/simple_animal/hostile/statue/Move(turf/NewLoc) - if(can_be_seen(NewLoc)) - if(client) - to_chat(src, "You cannot move, there are eyes on you!") - return 0 - return ..() - -/mob/living/simple_animal/hostile/statue/Life() - ..() - handleAnnoyance() - if ((annoyance - 2) > 0) - annoyance -= 2 - if(target_mob) - if((annoyance + 5) < 800) - annoyance += 5 - -/mob/living/simple_animal/hostile/statue/handle_stance() - if(!..()) - return - if(target_mob) // If we have a target and we're AI controlled - var/mob/watching = can_be_seen() - // If they're not our target - if(watching && watching != target_mob) - // This one is closer. - if(get_dist(watching, src) > get_dist(target_mob, src)) - LoseTarget() - target_mob = watching - - -/mob/living/simple_animal/hostile/statue/proc/handleAnnoyance() - if(last_response + 3 SECONDS < world.time) //so it won't blind people 24/7 - return - var/turf/T = get_turf(loc) - if (annoyance > 60) - AI_blind() - annoyance -= 25 - if (prob(50)) - if(T.get_lumcount() * 10 > 1.5) - AI_flash() - annoyance -= 35 - last_response = world.time - return - - -/mob/living/simple_animal/hostile/statue/proc/AI_blind() - for(var/mob/living/L in range(7, src)) - if(L == src) - continue - if (prob(75)) - if(istype(L , /mob/living/carbon/human)) - var/mob/living/carbon/human/H = L - if (H.species == "Diona" || H.species == "Promethean")// can't blink and organic - return - to_chat(L, "Your eyes feel very heavy.") - L.Blind(5) - return - -/mob/living/simple_animal/hostile/statue/proc/AI_flash() - if (prob(60)) - visible_message("The statue slowly points at the light.") - for(var/obj/machinery/light/L in range(10, src)) - L.flicker() - return - - -/mob/living/simple_animal/hostile/statue/proc/AI_mirrorshmash() - for(var/obj/structure/mirror/M in range(10, src)) - if ((!M.shattered )||(!M.glass)) - visible_message("The mirror shatters!") - M.shatter() - return - - - -/mob/living/simple_animal/hostile/statue/AttackTarget() - if(can_be_seen(get_turf(loc))) - if(client) - to_chat(src, "You cannot attack, there are eyes on you!") - return - else if(prob(80)) - spawn(4) - ..() - - - -/mob/living/simple_animal/hostile/statue/face_atom() - if(!can_be_seen(get_turf(loc))) - ..() - -/mob/living/simple_animal/hostile/statue/proc/can_be_seen(turf/destination) - if(!cannot_be_seen) - return null - // Check for darkness - var/turf/T = get_turf(loc) - if(T && destination && T.lighting_overlay) - if(T.get_lumcount() * 10 < 1 && destination.get_lumcount() * 10 < 1) // No one can see us in the darkness, right? - return null - if(T == destination) - destination = null - - // We aren't in darkness, loop for viewers. - var/list/check_list = list(src) - if(destination) - check_list += destination - - // This loop will, at most, loop twice. - for(var/atom/check in check_list) - for(var/mob/living/M in viewers(world.view + 1, check) - src) - if(!(M.sdisabilities & BLIND) || !(M.blinded)) - if(M.has_vision() && !M.isSynthetic()) - return M - for(var/obj/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you - if(M.occupant && M.occupant.client) - if(M.occupant.has_vision() && !M.occupant.isSynthetic()) - return M.occupant - for(var/obj/structure/mirror/M in view(7, check)) //Weeping angels hate mirrors. Probably because they're ugly af - if ((!M.shattered )||(!M.glass)) - annoyance += 2 - if ((annoyance > 200) && (ai_inactive == 0)) - AI_mirrorshmash() - annoyance -= 200 - return src //if it sees the mirror, it sees itself, right? - return null - -// Cannot talk - -/mob/living/simple_animal/hostile/statue/say() - return 0 - -// Turn to dust when gibbed - -/mob/living/simple_animal/hostile/statue/gib() - dust() - - -// Stop attacking clientless mobs - -/mob/living/simple_animal/hostile/statue/proc/CanAttack(atom/the_target) //ignore clientless mobs - if(isliving(the_target)) - var/mob/living/L = the_target - if(!L.client && !L.ckey) - return 0 - return ..() - -// Statue powers - -// Flicker lights -/spell/aoe_turf/flicker_lights - name = "Flicker Lights" - desc = "You will trigger a large amount of lights around you to flicker." - spell_flags = 0 - charge_max = 400 - range = 14 - -/spell/aoe_turf/flicker_lights/cast(list/targets, mob/user = usr) - for(var/turf/T in targets) - for(var/obj/machinery/light/L in T) - L.flicker() - return - -//Blind AOE -/spell/aoe_turf/blindness - name = "Blindness" - desc = "Your prey will be momentarily blind for you to advance on them." - - message = "You glare your eyes." - charge_max = 250 - spell_flags = 0 - range = 10 - -/spell/aoe_turf/blindness/cast(list/targets, mob/user = usr) - for(var/mob/living/L in living_mob_list) - if(L == user) - continue - var/turf/T = get_turf(L.loc) - if(T && T in targets) - L.Blind(7) - return - - -/spell/aoe_turf/shatter - name = "Shatter mirrors!" - desc = "That handsome devil has to wait. You have people to make into corpses." - - message = "You glare your eyes." - charge_max = 2000 - silenced = 500 - spell_flags = 0 - range = 10 - - - - -/spell/aoe_turf/shatter/cast(list/targets, mob/user = usr) - for(var/obj/structure/mirror/M in range(10, src)) - if ((!M.shattered )||(!M.glass)) - M.shatter() - return - - - -/mob/living/simple_animal/hostile/statue/verb/toggle_darkness() - set name = "Toggle Darkness" - set desc = "You ARE the darkness." - set category = "Abilities" - seedarkness = !seedarkness - plane_holder.set_vis(VIS_FULLBRIGHT, !seedarkness) - to_chat(src,"You [seedarkness ? "now" : "no longer"] see darkness.") - - - -/mob/living/simple_animal/hostile/statue/restrained() - . = ..() - if(can_be_seen(loc)) - return 1 - - - -/mob/living/simple_animal/hostile/statue/ListTargets() - . = ..() - - for(var/mob/living/V in mobs_in_xray_view(20, src)) - . += V - - - return . diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 9b0ca19ed56..c8b78cfd654 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -33,14 +33,11 @@ var/global/photo_count = 0 var/icon/img //Big photo image var/scribble //Scribble on the back. var/icon/tiny - var/cursed = 0 var/photo_size = 3 /obj/item/weapon/photo/New() id = photo_count++ - - /obj/item/weapon/photo/attack_self(mob/user as mob) user.examinate(src) @@ -236,11 +233,6 @@ var/global/photo_count = 0 mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]. " else mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]." - - for(var/mob/living/simple_animal/hostile/statue/S in the_turf) - if(S) - mob_detail += "You can see a [S] on the photo. Its stare makes you feel uneasy." //"That which holds the image of an angel, becomes itself an angel." - return mob_detail /obj/item/device/camera/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) @@ -282,16 +274,7 @@ var/global/photo_count = 0 y_c-- x_c = x_c - size - - - var/obj/item/weapon/photo/p = createpicture(target, user, turfs, mobs, flag) - if(findtext(mobs, "Its stare makes you feel uneasy")) - p.cursed = 1 - visible_message("Something starts to slowly manifest from the picture!") - spawn(150) - new /mob/living/simple_animal/hostile/statue(usr.loc) - printpicture(user, p) /obj/item/device/camera/proc/createpicture(atom/target, mob/user, list/turfs, mobs, flag) @@ -315,6 +298,7 @@ var/global/photo_count = 0 p.pixel_x = rand(-10, 10) p.pixel_y = rand(-10, 10) p.photo_size = size + return p /obj/item/device/camera/proc/printpicture(mob/user, obj/item/weapon/photo/p) @@ -334,11 +318,6 @@ var/global/photo_count = 0 p.pixel_y = pixel_y p.photo_size = photo_size p.scribble = scribble - p.cursed = cursed - if(p.cursed) - visible_message("Something starts to slowly manifest from the picture!") - spawn(150) - new /mob/living/simple_animal/hostile/statue(usr.loc) if(copy_id) p.id = id diff --git a/polaris.dme b/polaris.dme index b3db30781b3..0bb899cea27 100644 --- a/polaris.dme +++ b/polaris.dme @@ -1877,7 +1877,6 @@ #include "code\modules\mob\living\simple_animal\aliens\hivebot.dm" #include "code\modules\mob\living\simple_animal\aliens\mimic.dm" #include "code\modules\mob\living\simple_animal\aliens\shade.dm" -#include "code\modules\mob\living\simple_animal\aliens\statue.dm" #include "code\modules\mob\living\simple_animal\animals\bat.dm" #include "code\modules\mob\living\simple_animal\animals\bear.dm" #include "code\modules\mob\living\simple_animal\animals\carp.dm" @@ -2429,7 +2428,6 @@ #include "code\ZAS\Zone.dm" #include "interface\interface.dm" #include "interface\skin.dmf" -#include "maps\northern_star\northern_star.dm" #include "maps\southern_cross\southern_cross.dm" #include "maps\submaps\_readme.dm" #include "maps\submaps\space_submaps\space.dm" From f75ea72480cf855e3fff265038e364c3e8a1090c Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 17 Mar 2018 19:49:03 -0400 Subject: [PATCH 40/74] POLARIS: Improve robot and typing overlays --- .../preference_setup/global/setting_datums.dm | 2 +- .../client/preferences_toggle_procs.dm | 4 +- .../modules/mob/living/silicon/robot/robot.dm | 17 ++---- code/modules/mob/mob_defines.dm | 4 +- code/modules/mob/say.dm | 4 +- code/modules/mob/typing_indicator.dm | 55 +++++++------------ code/modules/multiz/zshadow.dm | 7 --- 7 files changed, 32 insertions(+), 61 deletions(-) diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm index a85befce774..a18fa2db63c 100644 --- a/code/modules/client/preference_setup/global/setting_datums.dm +++ b/code/modules/client/preference_setup/global/setting_datums.dm @@ -119,7 +119,7 @@ var/list/_client_preferences_by_type /datum/client_preference/show_typing_indicator/toggled(var/mob/preference_mob, var/enabled) if(!enabled) - preference_mob.set_typing_indicator(0) + preference_mob.set_typing_indicator(FALSE) /datum/client_preference/show_ooc description ="OOC chat" diff --git a/code/modules/client/preferences_toggle_procs.dm b/code/modules/client/preferences_toggle_procs.dm index bcd4e3a0c1a..4b225b55d49 100644 --- a/code/modules/client/preferences_toggle_procs.dm +++ b/code/modules/client/preferences_toggle_procs.dm @@ -98,11 +98,11 @@ toggle_preference(pref_path) - src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] see the speech indicator." + src << "You will [ (is_preference_enabled(pref_path)) ? "now" : "no longer"] have the speech indicator." prefs.save_preferences() - feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + feedback_add_details("admin_verb","TTIND") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/verb/toggle_ahelp_sound() set name = "Toggle Admin Help Sound" diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 589f410f012..82255877b2e 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -706,34 +706,29 @@ return 0 /mob/living/silicon/robot/updateicon() - overlays.Cut() + cut_overlays() if(stat == CONSCIOUS) - overlays += "eyes-[module_sprites[icontype]]" + add_overlay("eyes-[module_sprites[icontype]]") if(opened) var/panelprefix = custom_sprite ? "[src.ckey]-[src.name]" : "ov" if(wiresexposed) - overlays += "[panelprefix]-openpanel +w" + add_overlay("[panelprefix]-openpanel +w") else if(cell) - overlays += "[panelprefix]-openpanel +c" + add_overlay("[panelprefix]-openpanel +c") else - overlays += "[panelprefix]-openpanel -c" + add_overlay("[panelprefix]-openpanel -c") if(has_active_type(/obj/item/borg/combat/shield)) var/obj/item/borg/combat/shield/shield = locate() in src if(shield && shield.active) - overlays += "[module_sprites[icontype]]-shield" + add_overlay("[module_sprites[icontype]]-shield") if(modtype == "Combat") if(module_active && istype(module_active,/obj/item/borg/combat/mobility)) icon_state = "[module_sprites[icontype]]-roll" else icon_state = module_sprites[icontype] - return - - if(typing) - typing = FALSE - set_typing_indicator(1) /mob/living/silicon/robot/proc/installed_modules() if(weapon_lock) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index cc446a04887..cdc6b6af745 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -219,9 +219,7 @@ var/get_rig_stats = 0 //Moved from computer.dm - - var/hud_typing = 0 //Typing indicator stuff. - var/typing //Simple mobs use this variable. + var/typing var/obj/effect/decal/typing_indicator var/low_priority = FALSE //Skip processing life() if there's just no players on this Z-level diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index b5add4f23f9..206450c9098 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -11,7 +11,7 @@ set name = "Say" set category = "IC" - set_typing_indicator(0) + set_typing_indicator(FALSE) usr.say(message) /mob/verb/me_verb(message as text) @@ -24,7 +24,7 @@ message = sanitize(message) - set_typing_indicator(0) + set_typing_indicator(FALSE) if(use_me) usr.emote("me",usr.emote_type,message) else diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm index 5b164a84996..5f0d0894546 100644 --- a/code/modules/mob/typing_indicator.dm +++ b/code/modules/mob/typing_indicator.dm @@ -1,41 +1,34 @@ /mob/proc/set_typing_indicator(var/state) //Leaving this here for mobs. + if(!is_preference_enabled(/datum/client_preference/show_typing_indicator)) + cut_overlay(typing_indicator, TRUE) + return + if(!typing_indicator) typing_indicator = new typing_indicator.icon = 'icons/mob/talk.dmi' typing_indicator.icon_state = "[speech_bubble_appearance()]_typing" - if(client && !stat) - typing_indicator.invisibility = invisibility - if(!is_preference_enabled(/datum/client_preference/show_typing_indicator)) - add_overlay(typing_indicator) - else - if(state) - if(!typing) - add_overlay(typing_indicator) - typing = 1 - else - if(typing) - cut_overlay(typing_indicator) - typing = 0 - return state + if(state && !typing) + add_overlay(typing_indicator, TRUE) + typing = TRUE + else if(typing) + cut_overlay(typing_indicator, TRUE) + typing = FALSE + + if(shadow) //Multi-Z above-me shadows + shadow.set_typing_indicator(state) + + return state /mob/verb/say_wrapper() set name = ".Say" set hidden = 1 - if(!ishuman(src)) //If they're a mob, use the old code. - set_typing_indicator(1) - else if(is_preference_enabled(/datum/client_preference/show_typing_indicator)) - hud_typing = 1 - + set_typing_indicator(TRUE) var/message = input("","say (text)") as text - - if(!ishuman(src)) //If they're a mob, use the old code. - set_typing_indicator(0) - else if(is_preference_enabled(/datum/client_preference/show_typing_indicator)) - hud_typing = 0 - + set_typing_indicator(FALSE) + if(message) say_verb(message) @@ -43,17 +36,9 @@ set name = ".Me" set hidden = 1 - if(!ishuman(src)) //If they're a mob, use the old code. - set_typing_indicator(1) - else if(is_preference_enabled(/datum/client_preference/show_typing_indicator)) - hud_typing = 1 - + set_typing_indicator(TRUE) var/message = input("","me (text)") as text - - if(is_preference_enabled(/datum/client_preference/show_typing_indicator)) - hud_typing = 0 - else if(!ishuman(src)) //If they're a mob, use the old code. - set_typing_indicator(0) + set_typing_indicator(FALSE) if(message) me_verb(message) diff --git a/code/modules/multiz/zshadow.dm b/code/modules/multiz/zshadow.dm index 10af55f5a3b..f5648abf592 100644 --- a/code/modules/multiz/zshadow.dm +++ b/code/modules/multiz/zshadow.dm @@ -117,13 +117,6 @@ if(shadow) shadow.visible_message(message, self_message, blind_message) -// We should show the typing indicator so people above us can tell we're about to talk. -/mob/set_typing_indicator(var/state) - var/old_typing = src.typing - . = ..() - if(shadow && old_typing != src.typing) - shadow.set_typing_indicator(state) // Okay the real proc changed something! That means we should handle things too - /mob/zshadow/set_typing_indicator(var/state) if(!typing_indicator) typing_indicator = new From 59844c5553c6ea40443793857ece5956905f3fe6 Mon Sep 17 00:00:00 2001 From: Cameron653 Date: Thu, 22 Mar 2018 12:50:50 -0400 Subject: [PATCH 41/74] Xenoarch Multitool & Xenoarch Excavation Drill (#5058) * Xenoarch Multitool & Xenoarch Excavation Drill * Makes the tool work better * Cuts down on lines & left comments * change to m --- .../objects/items/weapons/storage/belt.dm | 4 +- code/modules/mining/mine_turfs.dm | 30 +++++++---- code/modules/research/designs.dm | 16 ++++++ code/modules/xenoarcheaology/boulder.dm | 19 +++++-- code/modules/xenoarcheaology/tools/tools.dm | 48 +++++++++++++++--- .../xenoarcheaology/tools/tools_pickaxe.dm | 40 +++++++++++++++ .../Cameron - Xenoarch Upgrades.yml | 37 ++++++++++++++ icons/obj/xenoarchaeology.dmi | Bin 68454 -> 69275 bytes 8 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 html/changelogs/Cameron - Xenoarch Upgrades.yml diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 48593c7b21c..e4482932b1b 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -373,7 +373,9 @@ /obj/item/weapon/storage/excavation, /obj/item/weapon/anobattery, /obj/item/device/ano_scanner, - /obj/item/weapon/pickaxe/hand + /obj/item/weapon/pickaxe/hand, + /obj/item/device/xenoarch_multi_tool, + /obj/item/weapon/pickaxe/excavationdrill ) /obj/item/weapon/storage/belt/fannypack diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index ced8b138434..b59909376f7 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -243,7 +243,7 @@ var/list/mining_overlay_cache = list() /turf/simulated/mineral/attackby(obj/item/weapon/W as obj, mob/user as mob) if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") - usr << "You don't have the dexterity to do this!" + to_chat(user, "You don't have the dexterity to do this!") return if(!density) @@ -263,19 +263,19 @@ var/list/mining_overlay_cache = list() if(valid_tool) if (sand_dug) - user << "This area has already been dug." + to_chat(user, "This area has already been dug.") return var/turf/T = user.loc if (!(istype(T))) return - user << "You start digging." + to_chat(user, "You start digging.") playsound(user.loc, 'sound/effects/rustle1.ogg', 50, 1) if(!do_after(user,40)) return - user << "You dug a hole." + to_chat(user, "You dug a hole.") GetDrilled() else if(istype(W,/obj/item/weapon/storage/bag/ore)) @@ -298,7 +298,7 @@ var/list/mining_overlay_cache = list() return var/obj/item/stack/rods/R = W if (R.use(1)) - user << "Constructing support lattice ..." + to_chat(user, "Constructing support lattice ...") playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) new /obj/structure/lattice(get_turf(src)) @@ -314,7 +314,7 @@ var/list/mining_overlay_cache = list() S.use(1) return else - user << "The plating is going to need some support." + to_chat(user, "The plating is going to need some support.") return @@ -334,7 +334,17 @@ var/list/mining_overlay_cache = list() var/obj/item/device/measuring_tape/P = W user.visible_message("\The [user] extends \a [P] towards \the [src].","You extend \the [P] towards \the [src].") if(do_after(user, 15)) - user << "\The [src] has been excavated to a depth of [excavation_level]cm." + to_chat(user, "\The [src] has been excavated to a depth of [excavation_level]cm.") + return + + if(istype(W, /obj/item/device/xenoarch_multi_tool)) + var/obj/item/device/xenoarch_multi_tool/C = W + if(C.mode) //Mode means scanning + C.depth_scanner.scan_atom(user, src) + else + user.visible_message("\The [user] extends \the [C] over \the [src], a flurry of red beams scanning \the [src]'s surface!", "You extend \the [C] over \the [src], a flurry of red beams scanning \the [src]'s surface!") + if(do_after(user, 15)) + to_chat(user, "\The [src] has been excavated to a depth of [excavation_level]cm.") return if (istype(W, /obj/item/weapon/pickaxe)) @@ -356,7 +366,7 @@ var/list/mining_overlay_cache = list() if(newDepth > F.excavation_required) // Digging too deep can break the item. At least you won't summon a Balrog (probably) fail_message = ". [pick("There is a crunching noise","[W] collides with some different rock","Part of the rock face crumbles away","Something breaks under [W]")]" - user << "You start [P.drill_verb][fail_message]." + to_chat(user, "You start [P.drill_verb][fail_message].") if(fail_message && prob(90)) if(prob(25)) @@ -375,7 +385,7 @@ var/list/mining_overlay_cache = list() else if(newDepth > F.excavation_required - F.clearance_range) // Not quite right but you still extract your find, the closer to the bottom the better, but not above 80% excavate_find(prob(80 * (F.excavation_required - newDepth) / F.clearance_range), F) - user << "You finish [P.drill_verb] \the [src]." + to_chat(user, "You finish [P.drill_verb] \the [src].") if(newDepth >= 200) // This means the rock is mined out fully var/obj/structure/boulder/B @@ -480,7 +490,7 @@ var/list/mining_overlay_cache = list() if(prob(50)) pain = 1 for(var/mob/living/M in range(src, 200)) - M << "[pick("A high-pitched [pick("keening","wailing","whistle")]","A rumbling noise like [pick("thunder","heavy machinery")]")] somehow penetrates your mind before fading away!" + to_chat(M, "[pick("A high-pitched [pick("keening","wailing","whistle")]","A rumbling noise like [pick("thunder","heavy machinery")]")] somehow penetrates your mind before fading away!") if(pain) flick("pain",M.pain) if(prob(50)) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 649d041db21..f90fd1c313c 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -1802,6 +1802,22 @@ CIRCUITS BELOW build_path = /obj/item/device/universal_translator/ear sort_string = "HABQB" +/datum/design/obj/item/device/xenoarch_multi_tool + name = "xenoarcheology multitool" + id = "xenoarch_multitool" + req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3, TECH_BLUESPACE = 3) + build_path = /obj/item/device/xenoarch_multi_tool + materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "uranium" = 500, "phoron" = 500) + sort_string = "HABQC" + +/datum/design/excavationdrill + name = "Excavation Drill" + id = "excavationdrill" + req_tech = list(TECH_MATERIAL = 3, TECH_POWER = 2, TECH_ENGINEERING = 2, TECH_BLUESPACE = 3) + build_type = PROTOLATHE + materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 4000) + build_path = /obj/item/weapon/pickaxe/excavationdrill + /* Uncomment if someone makes these buildable /datum/design/circuit/general_alert name = "general alert console" diff --git a/code/modules/xenoarcheaology/boulder.dm b/code/modules/xenoarcheaology/boulder.dm index 4c0bafd7071..09b9d398ea8 100644 --- a/code/modules/xenoarcheaology/boulder.dm +++ b/code/modules/xenoarcheaology/boulder.dm @@ -29,11 +29,22 @@ C.scan_atom(user, src) return + if(istype(I, /obj/item/device/xenoarch_multi_tool)) + var/obj/item/device/xenoarch_multi_tool/C = I + if(C.mode) //Mode means scanning. + C.depth_scanner.scan_atom(user, src) + return + else + user.visible_message("\The [user] extends \the [C] over \the [src], a flurry of red beams scanning \the [src]'s surface!", "You extend \the [C] over \the [src], a flurry of red beams scanning \the [src]'s surface!") + if(do_after(user, 15)) + to_chat(user, "\The [src] has been excavated to a depth of [2 * src.excavation_level]cm.") + return + if(istype(I, /obj/item/device/measuring_tape)) var/obj/item/device/measuring_tape/P = I user.visible_message("\The [user] extends \the [P] towards \the [src].", "You extend \the [P] towards \the [src].") if(do_after(user, 15)) - user << "\The [src] has been excavated to a depth of [2 * src.excavation_level]cm." + to_chat(user, "\The [src] has been excavated to a depth of [2 * src.excavation_level]cm.") return if(istype(I, /obj/item/weapon/pickaxe)) @@ -43,12 +54,12 @@ return last_act = world.time - user << "You start [P.drill_verb] [src]." + to_chat(user, "You start [P.drill_verb] [src].") if(!do_after(user, P.digspeed)) return - user << "You finish [P.drill_verb] [src]." + to_chat(user, "You finish [P.drill_verb] [src].") excavation_level += P.excavation_amount if(excavation_level > 100) @@ -87,4 +98,4 @@ else if(istype(AM,/obj/mecha)) var/obj/mecha/M = AM if(istype(M.selected,/obj/item/mecha_parts/mecha_equipment/tool/drill)) - M.selected.action(src) \ No newline at end of file + M.selected.action(src) diff --git a/code/modules/xenoarcheaology/tools/tools.dm b/code/modules/xenoarcheaology/tools/tools.dm index 17412b4a8be..5f8c30ecad9 100644 --- a/code/modules/xenoarcheaology/tools/tools.dm +++ b/code/modules/xenoarcheaology/tools/tools.dm @@ -80,13 +80,13 @@ SSxenoarch.digsite_spawning_turfs.Remove(T) if(nearestTargetDist >= 0) - user << "Exotic energy detected on wavelength '[nearestTargetId]' in a radius of [nearestTargetDist]m[nearestSimpleTargetDist > 0 ? "; small anomaly detected in a radius of [nearestSimpleTargetDist]m" : ""]" + to_chat(user, "Exotic energy detected on wavelength '[nearestTargetId]' in a radius of [nearestTargetDist]m[nearestSimpleTargetDist > 0 ? "; small anomaly detected in a radius of [nearestSimpleTargetDist]m" : ""]") else if(nearestSimpleTargetDist >= 0) - user << "Small anomaly detected in a radius of [nearestSimpleTargetDist]m." + to_chat(user, "Small anomaly detected in a radius of [nearestSimpleTargetDist]m.") else - user << "Background radiation levels detected." + to_chat(user, "Background radiation levels detected.") else - user << "Scanning array is recharging." + to_chat(user, "Scanning array is recharging.") /obj/item/device/depth_scanner name = "depth analysis scanner" @@ -133,7 +133,7 @@ positive_locations.Add(D) - user << "\icon[src] [src] pings." + to_chat(user, "\icon[src] [src] pings.") else if(istype(A, /obj/structure/boulder)) var/obj/structure/boulder/B = A @@ -151,7 +151,7 @@ positive_locations.Add(D) - user << "\icon[src] [src] pings [pick("madly","wildly","excitedly","crazily")]!" + to_chat(user, "\icon[src] [src] pings [pick("madly","wildly","excitedly","crazily")]!") /obj/item/device/depth_scanner/attack_self(var/mob/living/user) interact(user) @@ -310,3 +310,39 @@ usr << browse(null, "window=locater") updateSelfDialog() + +/obj/item/device/xenoarch_multi_tool + name = "xenoarcheology multitool" + desc = "Has the features of the Alden-Saraspova counter, a measuring tape, and a depth analysis scanner all in one!" + icon_state = "ano_scanner2" + item_state = "lampgreen" + icon = 'icons/obj/xenoarchaeology.dmi' + origin_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3, TECH_BLUESPACE = 2) + matter = list(DEFAULT_WALL_MATERIAL = 10000,"glass" = 5000) + w_class = ITEMSIZE_SMALL + slot_flags = SLOT_BELT + var/mode = 1 //Start off scanning. 1 = scanning, 0 = measuring + var/obj/item/device/ano_scanner/anomaly_scanner = null + var/obj/item/device/depth_scanner/depth_scanner = null + +/obj/item/device/xenoarch_multi_tool/New() + anomaly_scanner = new/obj/item/device/ano_scanner(src) + depth_scanner = new/obj/item/device/depth_scanner(src) + +/obj/item/device/xenoarch_multi_tool/attack_self(var/mob/living/user) + depth_scanner.interact(user) + +/obj/item/device/xenoarch_multi_tool/verb/swap_settings(var/mob/living/user) + set name = "Swap Functionality" + set desc = "Swap between the scanning and measuring functionality.." + mode = !mode + if(mode) + to_chat(user, "The device will now scan for artifacts.") + else + to_chat(user, "The device will now measure depth dug.") + +/obj/item/device/xenoarch_multi_tool/verb/scan_for_anomalies(var/mob/living/user) + set name = "Scan for Anomalies" + set desc = "Scan for artifacts and anomalies within your vicinity." + anomaly_scanner.interact(user) + diff --git a/code/modules/xenoarcheaology/tools/tools_pickaxe.dm b/code/modules/xenoarcheaology/tools/tools_pickaxe.dm index b954d5eb054..d911843cca2 100644 --- a/code/modules/xenoarcheaology/tools/tools_pickaxe.dm +++ b/code/modules/xenoarcheaology/tools/tools_pickaxe.dm @@ -149,3 +149,43 @@ smallest.loc = src picksToSort -= smallest orient2hud() + +/obj/item/weapon/pickaxe/excavationdrill + name = "excavation drill" + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "excavationdrill2" + item_state = "syringe_0" + excavation_amount = 15 + digspeed = 30 + desc = "Advanced archaeological drill combining ultrasonic excitation and bluespace manipulation to provide extreme precision. The tip is adjustable from 1 to 30 cm." + drill_sound = 'sound/weapons/thudswoosh.ogg' + drill_verb = "drilling" + force = 5 + w_class = 2 + attack_verb = list("drilled") + +/obj/item/weapon/pickaxe/excavationdrill/attack_self(mob/user as mob) + var/depth = input("Put the desired depth (1-30 centimeters).", "Set Depth", 30) as num + if(depth>30 || depth<1) + to_chat(user, "Invalid depth.") + return + excavation_amount = depth + to_chat(user, "You set the depth to [depth]cm.") + switch(depth) + if(1 to 5) + icon_state = "excavationdrill0" + if(6 to 10) + icon_state = "excavationdrill1" + if(11 to 15) + icon_state = "excavationdrill2" + if(16 to 20) + icon_state = "excavationdrill3" + if(21 to 25) + icon_state = "excavationdrill4" + if(25 to 30) + icon_state = "excavationdrill5" //The other 2 sprites are comically long. Let's just cut it at 5. + +/obj/item/weapon/pickaxe/excavationdrill/examine(mob/user) + ..() + var/depth = excavation_amount + to_chat(user, "It is currently set at [depth]cms.") \ No newline at end of file diff --git a/html/changelogs/Cameron - Xenoarch Upgrades.yml b/html/changelogs/Cameron - Xenoarch Upgrades.yml new file mode 100644 index 00000000000..b352e0d3b74 --- /dev/null +++ b/html/changelogs/Cameron - Xenoarch Upgrades.yml @@ -0,0 +1,37 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Cameron653 + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Adds a xenoarch excavation tool, craftable in R&D. Allows depth selection of 1-30" + - rscadd: "Adds a xenoarch multitool, craftable in R&D. Has xenoarch counter, measure tool, and depth scanner all in one." diff --git a/icons/obj/xenoarchaeology.dmi b/icons/obj/xenoarchaeology.dmi index 6ece09b46ed4dad3df6fb3f284dcf68ffc0be6f3..e0baa63cffdd9029210a36a49e89df5d5e6c9d56 100644 GIT binary patch delta 5643 zcma)gXH-)`xAqAT2)!4PjufRTQUvL}7ZnhJ2%$9|7|UA_HXy*vRRD5u!U*lSgqLAe`MH9J`8RN*KR>AUhc(_pSQfHfo8~-Oy!-raa``L}>WIdjEk07PotH*tL_NU-H1awLVVb{*l-llfb4! z*$1ERnuy45emcT}UT`zwFNC9|WF)9tDJ4Zsyo0WW7@q zh^PG!b%jrWkDEe7WX?g$5uAO50;rWGpUE0RCJv7<%Kj=w&ULFQt2B5SmxDaN)W z6k2YFa`CM5Jd>|HHhGh<%MS~qD4975;`r>7q2L(QzUiBzlE8ZX--m^>RiO{PWuzy7 z^Bj}x-Nf65%x}1^H4dzhi`E@?-f~xxLRnN$r`iQxp4wDf}R`&qS3cF1=mL|v)MX7PD zfZ^uTrndW3 zlSD;NBqlh?dyvO|=O^x9@=)q#@Gk@v+uGL}W766aP+2kIhH1B#&>xd;tQw^JjIm@l zIblJUl~Z0@-Zcw^T8=JPmAP=-w`Q_dkBsOxj{Ih9^qN17KNNUITS+%58qfaz{u`(z z`#VNh9NA4_Ck>`=#hOi=7Fb>L+?{#7GYjY;Hs?<1r=}+Csl}hOHh5S=Q_!A3$l+$B z=R%XK1xRb8ifh|N&mH?FmI89BU%i&vvbeDlsmSo9&>9F+A!|8gcajq*8W+WE&&|9z zB~feeT(F@X-e*0WM3pQBQ^6n4W#2ht@|8(A&+_ti^0;8t~b;DXiUhv@#%l=p?9(?WTc{u7f$H>g= zr%48R{v26Uu*|~5j4sI!p9&s7|0o=r-%Y5Ni$!&--g!W%XIDOMULa%Ok!-+;UP8@I zbsSEjJ=!g*8veDSZAqmO8$p@P_mh{VkRye3_AnY2st^VQ;Sv;7vw5f~xB|RgPis zEgD+~mVfnUwCPdc4&8pEDkaGoKr{y3+BO+B6k1Q+YrZD55thoVt%~bGZCWq`{0#y% z&ZE=6-Yo7|5|}mOn!So0%MlVbF-@?E)egG+=w0^LemuOV{5R zS(uv>K`==_8R7{1EkKNYrxPg1cx@z{mA9&`t*vKltZi?fH&|T=78Y9O=ic%YCMDB= z@yoN=(E-!t_a}d+U9F?KC5sz@h8h?cl&u8^2kYtSdEY8=XJ=!xb+m2r*Pm?%+fB>5rw+4?g!{idl#&e0ZPfmVm%4UMqdgqQ z6&t3Z5j7YZbPSrp_g*844$z+gNta}Fq~92&TV7zADbqLmbo9V-54-;~>9V}Z zZ1tmORle&6e}?6k-0Lh;umdRJLQ%)r4WS<=^n2g>`x!0n+!5Nq)vILW)iQ52MRMl21#P8?bq)lhf1&dKRP z^ukQXb;c%hgKcFy*h?=U0ONu{Xt=n@J9*?Jf6iEfxODx44!(EJ57OFo5$+JwP0>4E zK;}Pzro6(-x=rip6q!$PrunS(>VxFbkm~AcQ86*My2|qMo(d)aP(vU-WoBiG)HbO4 ztZMapHjr-4lOj1UU#|9;t2fE#J^Mr4(2DcFswatuJ$4J#8&0(NrnN^&oO>L3H%s^g zuD~*!CDjJfTwqy$9q?^5Wi>U@Vz_`!Y>&g~1Fz+Zb+;<->2`j-QeE^S*b2ZJy;n$R z$VoY+;Jxi7CUHN{FOdSsaRDG`yKd(Fj~~|7;%po=!^F zo9)22Z{FwJ)a;U(Y*O~(wE<7NVkjpH)T0@=xc*tQxXWcf@~HV~W^D}vW?EqvxQRrN z!ggDJtW?*+AbADAkMJuYy(0X`zN=(03$;ZR}=9IFOaI)n*V7>|*58Ya~>LH~OimlEIk5v9nySkDrQqb1WNcd3shZ z+foA^)%DimD$Q7M&$Y;DOcvdTq49HfcK^A4Z=?Kv&3kaF%!(S2M()^B0yku2pc~ss zNi+_NEx{9?9}kk{nmi+30FIku?-Yoc$lmrU6cxC7l`@)wUPoOWf;*fvCD8uKuh}xS z*hcaS2Anf*zPQcwfPT8$cT0e+RhE`7V? zB%faZtx|ukk*}OQCwx6yDBW|7rh`!dBqTsJ6|ezm{9{H17PECYR`cDu^;1N$cv*ha zmKry4t?bd9%S{6!Z|pwJZo!HTB$Soy21Z8MN{q9GArVsu?ZCkLf);x_J6hmJOK?rv z+qc)C6cn1M89|485CP3dJ!J+ivY2N;Kr+}-NvURG!4wsxi0_{?ZI?gST<`wC{UKR( zh5Z!!Hob07mpiLnN>MwE(7{yT6Ms%%Z=-m-b8l4DR|j%!#}|jYPfwCx-qNP((TUI} zOscfVdeD&FT&eLRzkPgeHWcDU$@$mK93D#9e9YVXPyWffen}F5F6=cN`R(F(@nfYO7Xn2^_ zW_{ZJDF9HF>uagsm4gr&in79q#e%k@(mfa&&GQJ+zQPuAAi6u^^XD5zucbTJbhk|M zRqO@^2ABXoC8Y;I#9)>bX_^$MwlU-9>l^cDvb0$N6VjS<8uN`E?w$6OUx$3KFQ;t7 zGl1aH4z!NAZlD$@Y)>qdz&+iLk54_$pRad(u?T*CyQq!0ReSXm3IGY~wb%1gp3C75t` zZz0+E4sgRkU>T*kgCf^;bQfMKa8>Fr`y=n5t2{e*Vnwhss~QWe;&WBhsNc94Xujpz z-$b92(*A>oa-cx%y%SO%GN4!J)IwVunq;^y8~p0*ZqdJd#P?o!3sQuR=XU&RtI|Cr zJ+I1qF%CT0U9m@kqOt83o2VuDZ|fXV2*42>%2DVx(2_^KVIof~I$efRt>1qWY@W}~ zb%(QV(=F`1B&f+%9V>gB`>2wNP_KXWG+%<(us1rVwQymr!@%)p9Sc$<-FWDaW^+5x z@s>AU!w(YF#1SuQF^Xcr7yGEKbMM!C+bVnu#{l=9>8GbrAcU3_zqFXcUllNfPREoBibmYeD%YyN7Zh3N_J;dD_85%lNq$IhvNp7_QSitE{Md z$QQRV1o8)0K;yg%_D}dZx@5=KURv4vxMM@=J2BYx7v$rzk3ZCsmS~(-f(Qd~gR=5? zUWWAv@nuSbyAlbG*?px(Zv?*hT_>I!HvHfD!_)btdz)5Eyi+x)@7>BZ)bylN@)QzF z@9aRYJj6|p?k4ToAG&_h!lwv+_)HQ9iIztE1D$?(TGJoA`kj){yD;}&NCuo)w|RI> z8qrkby8=hDs1?q^*Cd_2@6wSJB)5OY+c21+nmAcmS-E$xB*nY(n-K`!kj!feP$4Q) zW8;_go(o&P<&Rlyb!(C8*a3n|lP&Z^Z2Mv0a-Q2Hbj+M735SOmEmI zQdjEq`0=gTsmy*Ef5qUF$j_GcNKX_sEDh`}6zzIKf#8J9u?Bx+j~uiDE4iEH#QS*9 z+vmw`H&MB&`#uFTcVA+FkY@AS|@s5T}O0X*WO$?Ih1%ly{!;lEgoY96&)d z6PobpL3}6H2N+~{`#hzY1c;ujK!HMl>nJa=j6raZuHSS81iCf$w#PNd$jLjx>nMxW zkq_76XuG11>6tAn!62(fCWfen8PCjV&spJ$fuG_MHm&vv@vy#45gwm1n%#2pj_T(C+EeF9civ?a5%2a3N>NcK8h1LpGSF1 zn}!iC(Gm#x?dV0clr$fp9vR879hk(8k@k;_RLkIYE~{*8L4Pq9jM>mh-rV)tr1CT+ zb9#zW(=fVW<{5d4(aK+ptpAF56#4yf|Az=@&CnK>Jz3sB8Kd?RCO*59+lAISP)a3u zd2#Rox|3iBCMp7*q(cetNF&eNUNQSPIXUSO?`HJA78lik7MJSzE@?!iDVYYbMVmy6 z5qi%}izl)8q`A;dvw;4D8Ijb^SKDw$Q++a(xg*{DR}$qAZ{`X&;M(6vinG7oXSRLH zW(z_dwYJt)*Wl>8n^yH^uM+niTP!;o`mB2Z5a4M{Q4$o?e60$$Io15ELQGv#|MOT0 z#6P73UP;R$7G!?w-r*~>pV2ht7kXglsU=~$| zu(9u-7Z0qgHYW6)4}K3zy5`(;O|NyGEV2CKi4OShZV!iQ+f8C%V-$Mq5lX)j8MsLr zS+fx5aQsSJWi)!hi^Muz>S_@%L~Vb!wdyruC@a$(_&dCXoz%H3^q3`rEw*?%T-Hpo zBQB0y)WavRd0`w+elr!tstt|{O?c`LCcX?O#v$nJXCLuoii?;Q)z{OBZIqU!m)6in zWS?mA0z`GvAjzXlJJxswKC!w3cldPuKbGI4)_h`r=YgB*g&ty0CAs)AW zq!;me=pFu_GNbwbE>5G%hd$Id%$N;P4qi~~l<$8>Y(%|SRQZ2_(>l`G!xi>-Z{!`u zkhO%INaNSuJ+n=5W@la5E>GpdFA?~pcLFze+IW-U+urV8s9V3y$)_$63WMDkIsCFs zC&n%j&>|yR59ha4^fjH&4I9GOyn~f!bCn4rl3pe6#5R`LT{pK*j{`a9ZxMD%BI!v5 zdO%lJz1a$^a8V%YOUx5bJW!2?)#jWU=ybP;8JyIEZpjRkxr{=>o|~ab?5Z> z$;t-tX}Pk|e|mhAc2R+l_x@cO{)nV=q$HBKQ+UH{NXJ1KRt`Ngtyr)7wWpx`9pu%l z%@tjpE{g|=8f8;Hw*5&)^u3|}$J>=lr@#oWRQF1fTk166$fZf&X!>O zf_`+vC}=ggoOrNg&PhzuYI`FYFtE@UxrK0VIhy_D_BXY#2m+|9t5?}nD6lX`E3dBu zW7lMS8VOLRbsnca3{_G=kulWgU5NC%>>YpZzZ88N`j zh$(E3clIAC@D0gtfO)jv6cCjTxt}}B#oF>_Z;UABwoZSNsl^i}eoJ@M*516TsK{yf zN}LgR*ck;)AAWLYTQd3rXCDzKNCdj@Ji=Y>^6#NHf)`El@KEYSj73w}7mRBSIgp0d z$T^-Gd3vE@m$3IqFZ_BE+4coPluWR$iV+25&!2Qz_aqA(Z^I*^D#}tKfZvz Mwux4y#>1%p0`zCH1^@s6 delta 4816 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 Date: Thu, 22 Mar 2018 11:55:49 -0500 Subject: [PATCH 42/74] Ports antibiotics overhaul (#5050) * Ports antibiotics overhaul * Update the rest of the places "spaceacillin" is used where antibiotics is meant. * Antibiotics port compiles --- code/__defines/chemistry.dm | 7 +++- .../modules/organs/internal/organ_internal.dm | 6 +-- code/modules/organs/organ.dm | 22 +++++------ code/modules/organs/organ_external.dm | 10 ++--- code/modules/reagents/Chemistry-Reagents.dm | 2 +- .../Chemistry-Reagents-Medicine.dm | 37 ++++++++++++++++++- code/modules/reagents/Chemistry-Recipes.dm | 8 ++++ code/modules/virus2/disease2.dm | 2 +- code/modules/virus2/helpers.dm | 2 +- 9 files changed, 72 insertions(+), 24 deletions(-) diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm index 08131f99bb3..c9b34fc2b6a 100644 --- a/code/__defines/chemistry.dm +++ b/code/__defines/chemistry.dm @@ -27,7 +27,7 @@ #define IS_SLIME 8 #define CE_STABLE "stable" // Inaprovaline -#define CE_ANTIBIOTIC "antibiotic" // Spaceacilin +#define CE_ANTIBIOTIC "antibiotic" // Antibiotics #define CE_BLOODRESTORE "bloodrestore" // Iron/nutriment #define CE_PAINKILLER "painkiller" #define CE_ALCOHOL "alcohol" // Liver filtering @@ -36,6 +36,11 @@ #define REAGENTS_PER_SHEET 20 +// Attached to CE_ANTIBIOTIC +#define ANTIBIO_NORM 1 +#define ANTIBIO_OD 2 +#define ANTIBIO_SUPER 3 + // Chemistry lists. var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglycerin", "thirteenloko", "nicotine") // Increase heart rate. var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate. diff --git a/code/modules/organs/internal/organ_internal.dm b/code/modules/organs/internal/organ_internal.dm index 43b3a4c4d7f..58ed176505d 100644 --- a/code/modules/organs/internal/organ_internal.dm +++ b/code/modules/organs/internal/organ_internal.dm @@ -52,13 +52,13 @@ . = ..() //Should be an interger value for infection level if(!.) return - var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") + var/antibiotics = owner.chem_effects[CE_ANTIBIOTIC] - if(. >= 2 && antibiotics < 5) //INFECTION_LEVEL_TWO + if(. >= 2 && antibiotics < ANTIBIO_NORM) //INFECTION_LEVEL_TWO if (prob(3)) take_damage(1,silent=prob(30)) - if(. >= 3 && antibiotics < 30) //INFECTION_LEVEL_THREE + if(. >= 3 && antibiotics < ANTIBIO_OD) //INFECTION_LEVEL_THREE if (prob(50)) take_damage(1,silent=prob(15)) diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index abd388c930a..e26ea193749 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -148,25 +148,25 @@ var/list/organ_cache = list() germ_level = 0 return 0 - var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") + var/antibiotics = owner.chem_effects[CE_ANTIBIOTIC] || 0 var/infection_damage = 0 - if((status & ORGAN_DEAD) && antibiotics < 30) //Sepsis from 'dead' organs + if((status & ORGAN_DEAD) && antibiotics < ANTIBIO_OD) //Sepsis from 'dead' organs infection_damage = min(1, 1 + round((germ_level - INFECTION_LEVEL_THREE)/200,0.25)) //1 Tox plus a little based on germ level - else if(germ_level > INFECTION_LEVEL_TWO && antibiotics < 30) + else if(germ_level > INFECTION_LEVEL_TWO && antibiotics < ANTIBIO_OD) infection_damage = min(0.25, 0.25 + round((germ_level - INFECTION_LEVEL_TWO)/200,0.25)) if(infection_damage) owner.adjustToxLoss(infection_damage) if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30)) - adjust_germ_level(-1) + adjust_germ_level(-antibiotics) if (germ_level >= INFECTION_LEVEL_ONE/2) //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes - if(antibiotics < 5 && prob(round(germ_level/6))) + if(!antibiotics && prob(round(germ_level/6))) adjust_germ_level(1) if(germ_level >= INFECTION_LEVEL_ONE) @@ -181,7 +181,7 @@ var/list/organ_cache = list() . = 2 //Organ qualifies for effect-specific processing //No particular effect on the general 'organ' at 3 - if (germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) + if (germ_level >= INFECTION_LEVEL_THREE && antibiotics < ANTIBIO_OD) . = 3 //Organ qualifies for effect-specific processing adjust_germ_level(rand(5,10)) //Germ_level increases without overdose of antibiotics @@ -234,19 +234,19 @@ var/list/organ_cache = list() //Germs /obj/item/organ/proc/handle_antibiotics() - var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") + var/antibiotics = owner.chem_effects[CE_ANTIBIOTIC] || 0 - if (!germ_level || antibiotics < 5) + if (!germ_level || antibiotics < ANTIBIO_NORM) return if (germ_level < INFECTION_LEVEL_ONE) germ_level = 0 //cure instantly else if (germ_level < INFECTION_LEVEL_TWO) - adjust_germ_level(-6) //at germ_level < 500, this should cure the infection in a minute + adjust_germ_level(-antibiotics*4) //at germ_level < 500, this should cure the infection in a minute else if (germ_level < INFECTION_LEVEL_THREE) - adjust_germ_level(-2) //at germ_level < 1000, this will cure the infection in 5 minutes + adjust_germ_level(-antibiotics*2) //at germ_level < 1000, this will cure the infection in 5 minutes else - adjust_germ_level(-1) // You waited this long to get treated, you don't really deserve this organ + adjust_germ_level(-antibiotics) // You waited this long to get treated, you don't really deserve this organ //Adds autopsy data for used_weapon. /obj/item/organ/proc/add_autopsy_data(var/used_weapon, var/damage) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 86a9f589e46..6becbcaaf43 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -621,13 +621,13 @@ Note that amputating the affected organ does in fact remove the infection from t handle_germ_effects() /obj/item/organ/external/proc/handle_germ_sync() - var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") + var/antibiotics = owner.chem_effects[CE_ANTIBIOTIC] for(var/datum/wound/W in wounds) //Open wounds can become infected if (owner.germ_level > W.germ_level && W.infection_check()) W.germ_level++ - if (antibiotics < 5) + if (antibiotics < ANTIBIO_NORM) for(var/datum/wound/W in wounds) //Infected wounds raise the organ's germ level if (W.germ_level > germ_level) @@ -638,9 +638,9 @@ Note that amputating the affected organ does in fact remove the infection from t . = ..() //May be null or an infection level, if null then no specific processing needed here if(!.) return - var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin") + var/antibiotics = owner.chem_effects[CE_ANTIBIOTIC] - if(. >= 2 && antibiotics < 5) //INFECTION_LEVEL_TWO + if(. >= 2 && antibiotics < ANTIBIO_NORM) //INFECTION_LEVEL_TWO //spread the infection to internal organs var/obj/item/organ/target_organ = null //make internal organs become infected one at a time instead of all at once for (var/obj/item/organ/I in internal_organs) @@ -672,7 +672,7 @@ Note that amputating the affected organ does in fact remove the infection from t if (parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30)) parent.germ_level++ - if(. >= 3 && antibiotics < 30) //INFECTION_LEVEL_THREE + if(. >= 3 && antibiotics < ANTIBIO_OD) //INFECTION_LEVEL_THREE if (!(status & ORGAN_DEAD)) status |= ORGAN_DEAD owner << "You can't feel your [name] anymore..." diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 536ad9d2483..ce7227ce46f 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -108,7 +108,7 @@ /datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) return -/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect. Doesn't happen instantly. +/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect. if(alien == IS_DIONA) return if(ishuman(M)) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index b731f503268..d753d045d6e 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -509,11 +509,46 @@ taste_description = "bitterness" reagent_state = LIQUID color = "#C1C1C1" - metabolism = REM * 0.05 + metabolism = REM * 0.25 mrate_static = TRUE overdose = REAGENTS_OVERDOSE scannable = 1 +/datum/reagent/spaceacillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + ..() + M.add_chemical_effect(CE_ANTIBIOTIC, dose >= overdose ? ANTIBIO_OD : ANTIBIO_NORM) + +/datum/reagent/corophizine + name = "Corophizine" + id = "corophizine" + description = "A wide-spectrum antibiotic drug. Powerful and uncomfortable in equal doses." + taste_description = "burnt toast" + reagent_state = LIQUID + color = "#FFB0B0" + mrate_static = TRUE + overdose = 10 + scannable = 1 + +/datum/reagent/corophizine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + ..() + M.add_chemical_effect(CE_ANTIBIOTIC, ANTIBIO_SUPER) + + //Based roughly on Levofloxacin's rather severe side-effects + if(prob(20)) + M.Confuse(5) + if(prob(20)) + M.Weaken(5) + if(prob(20)) + M.make_dizzy(5) + if(prob(20)) + M.hallucination = max(M.hallucination, 10) + + //One of the levofloxacin side effects is 'spontaneous tendon rupture', which I'll immitate here. 1:1000 chance, so, pretty darn rare. + if(ishuman(M) && rand(1,1000) == 1) + var/mob/living/carbon/human/H = M + var/obj/item/organ/external/eo = pick(H.organs) //Misleading variable name, 'organs' is only external organs + eo.fracture() + /datum/reagent/sterilizine name = "Sterilizine" id = "sterilizine" diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 37634ac28a4..bb9358f8d0d 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -417,6 +417,14 @@ required_reagents = list("cryptobiolin" = 1, "inaprovaline" = 1) result_amount = 2 +/datum/chemical_reaction/corophizine + name = "Corophizine" + id = "corophizine" + result = "corophizine" + required_reagents = list("spaceacillin" = 1, "carbon" = 1, "phoron" = 0.1) + catalysts = list("phoron" = 5) + result_amount = 2 + /datum/chemical_reaction/imidazoline name = "imidazoline" id = "imidazoline" diff --git a/code/modules/virus2/disease2.dm b/code/modules/virus2/disease2.dm index 1b8ab86fd6a..3670f60beac 100644 --- a/code/modules/virus2/disease2.dm +++ b/code/modules/virus2/disease2.dm @@ -82,7 +82,7 @@ majormutate() //Space antibiotics have a good chance to stop disease completely - if(mob.reagents.has_reagent("spaceacillin")) + if(mob.chem_effects[CE_ANTIBIOTIC]) if(stage == 1 && prob(70-resistance)) src.cure(mob) else diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm index d10fdbfb686..64790fdfc59 100644 --- a/code/modules/virus2/helpers.dm +++ b/code/modules/virus2/helpers.dm @@ -81,7 +81,7 @@ proc/airborne_can_reach(turf/source, turf/target) var/list/antibodies_in_common = M.antibodies & disease.antigen if(antibodies_in_common.len) return - if(M.reagents.has_reagent("spaceacillin")) + if(M.chem_effects[CE_ANTIBIOTIC]) if(prob(disease.resistance)) var/datum/disease2/disease/D = disease.getcopy() D.minormutate() From ef6ccf82262f7cb3dee1d9d4230fc3a3799ad2df Mon Sep 17 00:00:00 2001 From: Verkister Date: Thu, 22 Mar 2018 19:06:40 +0200 Subject: [PATCH 43/74] Fixes the drone borg ID thing AGAIN. (#5080) * Fixes the drone borg ID thing --- code/game/jobs/job_controller.dm | 3 ++- code/modules/mob/living/carbon/human/human.dm | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 9db29ebd85b..d40330ca485 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -400,7 +400,8 @@ var/global/datum/controller/occupations/job_master job.equip_backpack(H) // job.equip_survival(H) job.apply_fingerprints(H) - H.equip_post_job() + if(job.title != "Cyborg" && job.title != "AI") + H.equip_post_job() //If some custom items could not be equipped before, try again now. for(var/thing in custom_equip_leftovers) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 09f6c62276f..b92ab586415 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1548,7 +1548,7 @@ return species.fire_icon_state // Called by job_controller. Makes drones start with a permit, might be useful for other people later too. -/mob/living/carbon/human/equip_post_job() //Drone Permit moved to equip_survival_gear() +/mob/living/carbon/human/equip_post_job() var/braintype = get_FBP_type() if(braintype == FBP_DRONE) var/turf/T = get_turf(src) From 4cbefc8cdf4281df605db03290792e58ab422b86 Mon Sep 17 00:00:00 2001 From: Mewchild Date: Thu, 22 Mar 2018 12:28:14 -0500 Subject: [PATCH 44/74] Updates tracking implant description --- code/game/objects/items/weapons/implants/implant.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index 1d515e863b4..2fb74579815 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -69,7 +69,7 @@ /obj/item/weapon/implant/tracking name = "tracking implant" - desc = "Track with this." + desc = "An implant normally given to dangerous criminals. Allows security to track your location." var/id = 1 var/degrade_time = 10 MINUTES //How long before the implant stops working outside of a living body. From c25fa6dea24a44114579fcefb76baea0d67ba830 Mon Sep 17 00:00:00 2001 From: Drexian Date: Fri, 23 Mar 2018 22:52:05 +0300 Subject: [PATCH 45/74] absolute pathing --- code/_helpers/icons.dm | 280 ++++++++++++++++++++--------------------- 1 file changed, 140 insertions(+), 140 deletions(-) diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index 64460aa8895..b3aa7112eba 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -634,168 +634,168 @@ as a single icon. Useful for when you want to manipulate an icon via the above a The _flatIcons list is a cache for generated icon files. */ -proc // Creates a single icon from a given /atom or /image. Only the first argument is required. - getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0, picture_planes = list(PLANE_WORLD)) - // We start with a blank canvas, otherwise some icon procs crash silently - var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon - if(!A) - return flat - if(A.alpha <= 0) - return flat - var/noIcon = FALSE + // Creates a single icon from a given /atom or /image. Only the first argument is required. +proc/getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0, picture_planes = list(PLANE_WORLD)) + // We start with a blank canvas, otherwise some icon procs crash silently + var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon + if(!A) + return flat + if(A.alpha <= 0) + return flat + var/noIcon = FALSE - var/curicon - if(A.icon) - curicon = A.icon + var/curicon + if(A.icon) + curicon = A.icon + else + curicon = deficon + + if(!curicon) + noIcon = TRUE // Do not render this object. + + var/curstate + if(A.icon_state) + curstate = A.icon_state + else + curstate = defstate + + if(!noIcon && !(curstate in icon_states(curicon))) + if("" in icon_states(curicon)) + curstate = "" else - curicon = deficon - - if(!curicon) noIcon = TRUE // Do not render this object. - var/curstate - if(A.icon_state) - curstate = A.icon_state - else - curstate = defstate + var/curdir + if(A.dir != 2 && !always_use_defdir) + curdir = A.dir + else + curdir = defdir - if(!noIcon && !(curstate in icon_states(curicon))) - if("" in icon_states(curicon)) - curstate = "" - else - noIcon = TRUE // Do not render this object. + var/curblend + if(A.blend_mode == BLEND_DEFAULT) + curblend = defblend + else + curblend = A.blend_mode - var/curdir - if(A.dir != 2 && !always_use_defdir) - curdir = A.dir - else - curdir = defdir + // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed + var/list/layers = list() + var/image/copy + // Add the atom's icon itself, without pixel_x/y offsets. + if(!noIcon) + copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=curdir) + copy.color = A.color + copy.alpha = A.alpha + copy.blend_mode = curblend + layers[copy] = A.layer - var/curblend - if(A.blend_mode == BLEND_DEFAULT) - curblend = defblend - else - curblend = A.blend_mode + // Loop through the underlays, then overlays, sorting them into the layers list + var/list/process = A.underlays // Current list being processed + var/pSet=0 // Which list is being processed: 0 = underlays, 1 = overlays + var/curIndex=1 // index of 'current' in list being processed + var/current // Current overlay being sorted + var/currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER) + var/compare // The overlay 'add' is being compared against + var/cmpIndex // The index in the layers list of 'compare' + while(TRUE) + if(curIndex<=process.len) + current = process[curIndex] + if(current) + var/currentPlane = current:plane + if (currentPlane != FLOAT_PLANE && !(currentPlane in picture_planes)) + curIndex++ + continue; + currentLayer = current:layer + if(currentLayer<0) // Special case for FLY_LAYER + if(currentLayer <= -1000) return flat + if(pSet == 0) // Underlay + currentLayer = A.layer+currentLayer/1000 + else // Overlay + currentLayer = A.layer+(1000+currentLayer)/1000 - // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed - var/list/layers = list() - var/image/copy - // Add the atom's icon itself, without pixel_x/y offsets. - if(!noIcon) - copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=curdir) - copy.color = A.color - copy.alpha = A.alpha - copy.blend_mode = curblend - layers[copy] = A.layer + // Sort add into layers list + for(cmpIndex=1,cmpIndex<=layers.len,cmpIndex++) + compare = layers[cmpIndex] + if(currentLayer < layers[compare]) // Associated value is the calculated layer + layers.Insert(cmpIndex,current) + layers[current] = currentLayer + break + if(cmpIndex>layers.len) // Reached end of list without inserting + layers[current]=currentLayer // Place at end - // Loop through the underlays, then overlays, sorting them into the layers list - var/list/process = A.underlays // Current list being processed - var/pSet=0 // Which list is being processed: 0 = underlays, 1 = overlays - var/curIndex=1 // index of 'current' in list being processed - var/current // Current overlay being sorted - var/currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER) - var/compare // The overlay 'add' is being compared against - var/cmpIndex // The index in the layers list of 'compare' - while(TRUE) - if(curIndex<=process.len) - current = process[curIndex] - if(current) - var/currentPlane = current:plane - if (currentPlane != FLOAT_PLANE && !(currentPlane in picture_planes)) - curIndex++ - continue; - currentLayer = current:layer - if(currentLayer<0) // Special case for FLY_LAYER - if(currentLayer <= -1000) return flat - if(pSet == 0) // Underlay - currentLayer = A.layer+currentLayer/1000 - else // Overlay - currentLayer = A.layer+(1000+currentLayer)/1000 + curIndex++ + else if(pSet == 0) // Switch to overlays + curIndex = 1 + pSet = 1 + process = A.overlays + else // All done + break - // Sort add into layers list - for(cmpIndex=1,cmpIndex<=layers.len,cmpIndex++) - compare = layers[cmpIndex] - if(currentLayer < layers[compare]) // Associated value is the calculated layer - layers.Insert(cmpIndex,current) - layers[current] = currentLayer - break - if(cmpIndex>layers.len) // Reached end of list without inserting - layers[current]=currentLayer // Place at end + var/icon/add // Icon of overlay being added - curIndex++ - else if(pSet == 0) // Switch to overlays - curIndex = 1 - pSet = 1 - process = A.overlays - else // All done - break + // Current dimensions of flattened icon + var/{flatX1=1;flatX2=flat.Width();flatY1=1;flatY2=flat.Height()} + // Dimensions of overlay being added + var/{addX1;addX2;addY1;addY2} - var/icon/add // Icon of overlay being added + for(var/I in layers) - // Current dimensions of flattened icon - var/{flatX1=1;flatX2=flat.Width();flatY1=1;flatY2=flat.Height()} - // Dimensions of overlay being added - var/{addX1;addX2;addY1;addY2} + if(I:alpha == 0) + continue - for(var/I in layers) - - if(I:alpha == 0) - continue - - if(I == copy) // 'I' is an /image based on the object being flattened. - curblend = BLEND_OVERLAY - add = icon(I:icon, I:icon_state, I:dir) - // This checks for a silent failure mode of the icon routine. If the requested dir - // doesn't exist in this icon state it returns a 32x32 icon with 0 alpha. - if (I:dir != SOUTH && add.Width() == 32 && add.Height() == 32) - // Check every pixel for blank (computationally expensive, but the process is limited - // by the amount of film on the station, only happens when we hit something that's - // turned, and bails at the very first pixel it sees. - var/blankpixel; - for(var/y;y<=32;y++) - for(var/x;x<32;x++) - blankpixel = isnull(add.GetPixel(x,y)) - if(!blankpixel) - break + if(I == copy) // 'I' is an /image based on the object being flattened. + curblend = BLEND_OVERLAY + add = icon(I:icon, I:icon_state, I:dir) + // This checks for a silent failure mode of the icon routine. If the requested dir + // doesn't exist in this icon state it returns a 32x32 icon with 0 alpha. + if (I:dir != SOUTH && add.Width() == 32 && add.Height() == 32) + // Check every pixel for blank (computationally expensive, but the process is limited + // by the amount of film on the station, only happens when we hit something that's + // turned, and bails at the very first pixel it sees. + var/blankpixel; + for(var/y;y<=32;y++) + for(var/x;x<32;x++) + blankpixel = isnull(add.GetPixel(x,y)) if(!blankpixel) break - // If we ALWAYS returned a null (which happens when GetPixel encounters something with alpha 0) - if (blankpixel) - // Pull the default direction. - add = icon(I:icon, I:icon_state) - else // 'I' is an appearance object. - add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, picture_planes = picture_planes) + if(!blankpixel) + break + // If we ALWAYS returned a null (which happens when GetPixel encounters something with alpha 0) + if (blankpixel) + // Pull the default direction. + add = icon(I:icon, I:icon_state) + else // 'I' is an appearance object. + add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, picture_planes = picture_planes) - // Find the new dimensions of the flat icon to fit the added overlay - addX1 = min(flatX1, I:pixel_x+1) - addX2 = max(flatX2, I:pixel_x+add.Width()) - addY1 = min(flatY1, I:pixel_y+1) - addY2 = max(flatY2, I:pixel_y+add.Height()) + // Find the new dimensions of the flat icon to fit the added overlay + addX1 = min(flatX1, I:pixel_x+1) + addX2 = max(flatX2, I:pixel_x+add.Width()) + addY1 = min(flatY1, I:pixel_y+1) + addY2 = max(flatY2, I:pixel_y+add.Height()) - if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2) - // Resize the flattened icon so the new icon fits - flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1) - flatX1=addX1;flatX2=addX2 - flatY1=addY1;flatY2=addY2 + if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2) + // Resize the flattened icon so the new icon fits + flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1) + flatX1=addX1;flatX2=addX2 + flatY1=addY1;flatY2=addY2 - // Blend the overlay into the flattened icon - flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1) + // Blend the overlay into the flattened icon + flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1) - if(A.color) - flat.Blend(A.color, ICON_MULTIPLY) - if(A.alpha < 255) - flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) + if(A.color) + flat.Blend(A.color, ICON_MULTIPLY) + if(A.alpha < 255) + flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) - return icon(flat, "", SOUTH) + return icon(flat, "", SOUTH) - getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N - var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. - for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. - if(I:layer>A.layer) continue//If layer is greater than what we need, skip it. - var/icon/image_overlay = new(I:icon,I:icon_state)//Blend only works with icon objects. - //Also, icons cannot directly set icon_state. Slower than changing variables but whatever. - alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. - return alpha_mask//And now return the mask. +proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N + var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. + for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. + if(I:layer>A.layer) continue//If layer is greater than what we need, skip it. + var/icon/image_overlay = new(I:icon,I:icon_state)//Blend only works with icon objects. + //Also, icons cannot directly set icon_state. Slower than changing variables but whatever. + alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. + return alpha_mask//And now return the mask. //getFlatIcon but generates an icon that can face ALL four directions. The only four. /proc/getCompoundIcon(atom/A) From 617aa580d93cdfed5ffbed6ebaf900566906ab7e Mon Sep 17 00:00:00 2001 From: Drexian Date: Fri, 23 Mar 2018 22:54:13 +0300 Subject: [PATCH 46/74] added slashes. No idea for what, but I don't want anyone to ask me to do it because they have OCD --- code/_helpers/icons.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index b3aa7112eba..e537351e4ec 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -635,7 +635,7 @@ The _flatIcons list is a cache for generated icon files. */ // Creates a single icon from a given /atom or /image. Only the first argument is required. -proc/getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0, picture_planes = list(PLANE_WORLD)) +/proc/getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0, picture_planes = list(PLANE_WORLD)) // We start with a blank canvas, otherwise some icon procs crash silently var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon if(!A) @@ -788,7 +788,7 @@ proc/getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DE return icon(flat, "", SOUTH) -proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N +/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. for(var/I in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. if(I:layer>A.layer) continue//If layer is greater than what we need, skip it. From 092b0f28a319cfe2ff3f1057c807e610e0c31929 Mon Sep 17 00:00:00 2001 From: Anewbe Date: Sat, 24 Mar 2018 17:42:36 -0500 Subject: [PATCH 47/74] Revert "Fixes cameras making completely black photos" --- code/_helpers/icons.dm | 183 +++++++++++++++++++++++++---------------- 1 file changed, 110 insertions(+), 73 deletions(-) diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index e537351e4ec..da4385ef6ff 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -634,16 +634,26 @@ as a single icon. Useful for when you want to manipulate an icon via the above a The _flatIcons list is a cache for generated icon files. */ - // Creates a single icon from a given /atom or /image. Only the first argument is required. -/proc/getFlatIcon(image/A, defdir=2, deficon=null, defstate="", defblend=BLEND_DEFAULT, always_use_defdir = 0, picture_planes = list(PLANE_WORLD)) +// Creates a single icon from a given /atom or /image. Only the first argument is required. +/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE) // We start with a blank canvas, otherwise some icon procs crash silently - var/icon/flat = icon('icons/effects/effects.dmi', "icon_state"="nothing") // Final flattened icon + var/icon/flat = icon('icons/effects/effects.dmi', "nothing") // Final flattened icon if(!A) return flat if(A.alpha <= 0) return flat var/noIcon = FALSE + if(start) + if(!defdir) + defdir = A.dir + if(!deficon) + deficon = A.icon + if(!defstate) + defstate = A.icon_state + if(!defblend) + defblend = A.blend_mode + var/curicon if(A.icon) curicon = A.icon @@ -666,10 +676,31 @@ The _flatIcons list is a cache for generated icon files. noIcon = TRUE // Do not render this object. var/curdir - if(A.dir != 2 && !always_use_defdir) - curdir = A.dir - else + var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have + + //These should use the parent's direction (most likely) + if(!A.dir || A.dir == SOUTH) curdir = defdir + else + curdir = A.dir + + //Let's check if the icon actually contains any diagonals, just skip if it's south to save (lot of) time + if(curdir != SOUTH) + var/icon/test_icon + var/directionals_exist = FALSE + var/list/dirs_to_check = cardinal - SOUTH + outer: + for(var/possible_dir in dirs_to_check) + test_icon = icon(curicon,curstate,possible_dir,frame=1) + for(var/x in 1 to world.icon_size) + for(var/y in 1 to world.icon_size) + if(!isnull(test_icon.GetPixel(x,y))) + directionals_exist = TRUE + break outer + if(!directionals_exist) + base_icon_dir = SOUTH + if(!base_icon_dir) + base_icon_dir = curdir var/curblend if(A.blend_mode == BLEND_DEFAULT) @@ -677,12 +708,18 @@ The _flatIcons list is a cache for generated icon files. else curblend = A.blend_mode + // Before processing overlays, make sure any pending overlays are applied + if (isloc(A)) + var/atom/aAtom = A + if(aAtom.flags & OVERLAY_QUEUED) + COMPILE_OVERLAYS(aAtom) + // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed var/list/layers = list() var/image/copy // Add the atom's icon itself, without pixel_x/y offsets. if(!noIcon) - copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=curdir) + copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir) copy.color = A.color copy.alpha = A.alpha copy.blend_mode = curblend @@ -699,78 +736,71 @@ The _flatIcons list is a cache for generated icon files. while(TRUE) if(curIndex<=process.len) current = process[curIndex] - if(current) - var/currentPlane = current:plane - if (currentPlane != FLOAT_PLANE && !(currentPlane in picture_planes)) - curIndex++ - continue; - currentLayer = current:layer - if(currentLayer<0) // Special case for FLY_LAYER - if(currentLayer <= -1000) return flat - if(pSet == 0) // Underlay - currentLayer = A.layer+currentLayer/1000 - else // Overlay - currentLayer = A.layer+(1000+currentLayer)/1000 + if(!current) + curIndex++ //Try the next layer + continue + var/image/I = current + if(I.plane != FLOAT_PLANE && I.plane != A.plane) + curIndex++ + continue + currentLayer = I.layer + if(currentLayer<0) // Special case for FLOAT_LAYER + if(currentLayer <= -1000) + return flat + if(pSet == 0) // Underlay + currentLayer = A.layer+currentLayer/1000 + else // Overlay + currentLayer = A.layer+(1000+currentLayer)/1000 - // Sort add into layers list - for(cmpIndex=1,cmpIndex<=layers.len,cmpIndex++) - compare = layers[cmpIndex] - if(currentLayer < layers[compare]) // Associated value is the calculated layer - layers.Insert(cmpIndex,current) - layers[current] = currentLayer - break - if(cmpIndex>layers.len) // Reached end of list without inserting - layers[current]=currentLayer // Place at end + // Sort add into layers list + for(cmpIndex=1,cmpIndex<=layers.len,cmpIndex++) + compare = layers[cmpIndex] + if(currentLayer < layers[compare]) // Associated value is the calculated layer + layers.Insert(cmpIndex,current) + layers[current] = currentLayer + break + if(cmpIndex>layers.len) // Reached end of list without inserting + layers[current]=currentLayer // Place at end curIndex++ - else if(pSet == 0) // Switch to overlays - curIndex = 1 - pSet = 1 - process = A.overlays - else // All done - break + + if(curIndex>process.len) + if(pSet == 0) // Switch to overlays + curIndex = 1 + pSet = 1 + process = A.overlays + else // All done + break var/icon/add // Icon of overlay being added - // Current dimensions of flattened icon - var/{flatX1=1;flatX2=flat.Width();flatY1=1;flatY2=flat.Height()} - // Dimensions of overlay being added - var/{addX1;addX2;addY1;addY2} + // Current dimensions of flattened icon + var/flatX1=1 + var/flatX2=flat.Width() + var/flatY1=1 + var/flatY2=flat.Height() + // Dimensions of overlay being added + var/addX1 + var/addX2 + var/addY1 + var/addY2 - for(var/I in layers) - - if(I:alpha == 0) + for(var/V in layers) + var/image/I = V + if(I.alpha == 0) continue if(I == copy) // 'I' is an /image based on the object being flattened. curblend = BLEND_OVERLAY - add = icon(I:icon, I:icon_state, I:dir) - // This checks for a silent failure mode of the icon routine. If the requested dir - // doesn't exist in this icon state it returns a 32x32 icon with 0 alpha. - if (I:dir != SOUTH && add.Width() == 32 && add.Height() == 32) - // Check every pixel for blank (computationally expensive, but the process is limited - // by the amount of film on the station, only happens when we hit something that's - // turned, and bails at the very first pixel it sees. - var/blankpixel; - for(var/y;y<=32;y++) - for(var/x;x<32;x++) - blankpixel = isnull(add.GetPixel(x,y)) - if(!blankpixel) - break - if(!blankpixel) - break - // If we ALWAYS returned a null (which happens when GetPixel encounters something with alpha 0) - if (blankpixel) - // Pull the default direction. - add = icon(I:icon, I:icon_state) + add = icon(I.icon, I.icon_state, base_icon_dir) else // 'I' is an appearance object. - add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, picture_planes = picture_planes) + add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, FALSE, no_anim) // Find the new dimensions of the flat icon to fit the added overlay - addX1 = min(flatX1, I:pixel_x+1) - addX2 = max(flatX2, I:pixel_x+add.Width()) - addY1 = min(flatY1, I:pixel_y+1) - addY2 = max(flatY2, I:pixel_y+add.Height()) + addX1 = min(flatX1, I.pixel_x+1) + addX2 = max(flatX2, I.pixel_x+add.Width()) + addY1 = min(flatY1, I.pixel_y+1) + addY2 = max(flatY2, I.pixel_y+add.Height()) if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2) // Resize the flattened icon so the new icon fits @@ -779,14 +809,20 @@ The _flatIcons list is a cache for generated icon files. flatY1=addY1;flatY2=addY2 // Blend the overlay into the flattened icon - flat.Blend(add, blendMode2iconMode(curblend), I:pixel_x + 2 - flatX1, I:pixel_y + 2 - flatY1) + flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1) if(A.color) flat.Blend(A.color, ICON_MULTIPLY) if(A.alpha < 255) flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) - return icon(flat, "", SOUTH) + if(no_anim) + //Clean up repeated frames + var/icon/cleaned = new /icon() + cleaned.Insert(flat, "", SOUTH, 1, 0) + return cleaned + else + return icon(flat, "", SOUTH) /proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. @@ -799,10 +835,10 @@ The _flatIcons list is a cache for generated icon files. //getFlatIcon but generates an icon that can face ALL four directions. The only four. /proc/getCompoundIcon(atom/A) - var/icon/north = getFlatIcon(A,defdir=NORTH,always_use_defdir=1) - var/icon/south = getFlatIcon(A,defdir=SOUTH,always_use_defdir=1) - var/icon/east = getFlatIcon(A,defdir=EAST,always_use_defdir=1) - var/icon/west = getFlatIcon(A,defdir=WEST,always_use_defdir=1) + var/icon/north = getFlatIcon(A,defdir=NORTH) + var/icon/south = getFlatIcon(A,defdir=SOUTH) + var/icon/east = getFlatIcon(A,defdir=EAST) + var/icon/west = getFlatIcon(A,defdir=WEST) //Starts with a blank icon because of byond bugs. var/icon/full = icon('icons/effects/effects.dmi', "icon_state"="nothing") @@ -818,7 +854,7 @@ The _flatIcons list is a cache for generated icon files. return full /proc/downloadImage(atom/A, dir) - var/icon/this_icon = getFlatIcon(A,defdir=dir||A.dir,always_use_defdir=1) + var/icon/this_icon = getFlatIcon(A,defdir=dir) usr << ftp(this_icon,"[A.name].png") @@ -886,7 +922,8 @@ proc/sort_atoms_by_layer(var/list/atoms) /proc/gen_hud_image(var/file, var/person, var/state, var/plane) var/image/img = image(file, person, state) img.plane = plane //Thanks Byond. - img.appearance_flags = APPEARANCE_UI|KEEP_APART + img.layer = MOB_LAYER-0.2 + img.appearance_flags = APPEARANCE_UI return img /** From 95877cc30a24e8b43f5408bc7c78a6958531c216 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 14:22:51 -0400 Subject: [PATCH 48/74] POLARIS: Fixes #3308 (VS) - Skrell lack eyes --- code/modules/organs/organ_icon.dm | 42 +++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index e7522a35313..971af563ee4 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -50,44 +50,60 @@ var/global/list/limb_icon_cache = list() if(eyes) eyes.update_colour() /obj/item/organ/external/head/get_icon() - ..() - overlays.Cut() + + //The overlays are not drawn on the mob, they are used for if the head is removed and becomes an item + cut_overlays() + + //Every 'addon' below requires information from species if(!owner || !owner.species) return - if(owner.should_have_organ(O_EYES)) + + //Eye color/icon + var/should_have_eyes = owner.should_have_organ(O_EYES) + var/has_eye_color = owner.species.appearance_flags & HAS_EYE_COLOR + if((should_have_eyes || has_eye_color) && eye_icon) var/obj/item/organ/internal/eyes/eyes = owner.internal_organs_by_name[O_EYES] - if(eye_icon) - var/icon/eyes_icon = new/icon(eye_icon_location, eye_icon) + var/icon/eyes_icon = new/icon(eye_icon_location, eye_icon) + //Should have eyes + if(should_have_eyes) + //And we have them if(eyes) eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD) + //They're gone! else eyes_icon.Blend(rgb(128,0,0), ICON_ADD) - mob_icon.Blend(eyes_icon, ICON_OVERLAY) - overlays |= eyes_icon - + //We have weird other-sorts of eyes (as we're not supposed to have eye organ, but we have HAS_EYE_COLOR species) + else + eyes_icon.Blend(rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes), ICON_ADD) + add_overlay(eyes_icon) + mob_icon.Blend(eyes_icon, ICON_OVERLAY) + + //Lip color/icon if(owner.lip_style && (species && (species.appearance_flags & HAS_LIPS))) var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") - overlays |= lip_icon + add_overlay(lip_icon) mob_icon.Blend(lip_icon, ICON_OVERLAY) - //Head markings. + //Head markings for(var/M in markings) var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]") mark_s.Blend(markings[M]["color"], ICON_ADD) - overlays |= mark_s //So when it's not on your body, it has icons + add_overlay(mark_s) //So when it's not on your body, it has icons mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons icon_cache_key += "[M][markings[M]["color"]]" + //Facial hair if(owner.f_style) var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style] if(facial_hair_style && facial_hair_style.species_allowed && (species.get_bodytype(owner) in facial_hair_style.species_allowed)) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") if(facial_hair_style.do_colouration) facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD) - overlays |= facial_s + add_overlay(facial_s) + //Head hair if(owner.h_style && !(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR))) var/datum/sprite_accessory/hair/hair_style = hair_styles_list[owner.h_style] if(hair_style && (species.get_bodytype(owner) in hair_style.species_allowed)) @@ -96,7 +112,7 @@ var/global/list/limb_icon_cache = list() if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3) hair_s.Blend(rgb(h_col[1], h_col[2], h_col[3]), ICON_MULTIPLY) hair_s.Blend(hair_s_add, ICON_ADD) - overlays |= hair_s + add_overlay(hair_s) return mob_icon From 7a02be815404fd3b62d2bd8650723d4c9b3b4a3c Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 14:34:58 -0400 Subject: [PATCH 49/74] POLARIS: Fixes #3280 (VS) - Typing as ghost removes overlays Also gives them the proper ghost speech bubble. Unsure why it wasn't used! --- code/modules/mob/dead/observer/observer.dm | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 7f151f8955f..246d7c16a33 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -103,12 +103,12 @@ if (ishuman(body)) var/mob/living/carbon/human/H = body icon = H.icon - underlays = H.underlays - overlays = H.overlays + icon_state = H.icon_state + add_overlay(H.overlays_standing) //All our equipment sprites else icon = body.icon icon_state = body.icon_state - overlays = body.overlays + add_overlay(body.overlays) gender = body.gender if(body.mind && body.mind.name) @@ -800,4 +800,7 @@ mob/observer/dead/MayRespawn(var/feedback = 0) if(PP.pai == null) PP.overlays += "pai-ghostalert" spawn(54) - PP.overlays.Cut() \ No newline at end of file + PP.overlays.Cut() + +/mob/observer/dead/speech_bubble_appearance() + return "ghost" From c4a6f8bae78388d3656b4690aaa97b30bcd0c5d9 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 14:47:05 -0400 Subject: [PATCH 50/74] POLARIS: Fixes #3298 (VS) - Observer-ghosts were naked instead of dressed --- code/modules/mob/new_player/new_player.dm | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index fa09155b639..1d49c1aacb6 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -115,7 +115,13 @@ if(alert(src,"Are you sure you wish to observe? You will have to wait 5 minutes before being able to respawn!","Player Setup","Yes","No") == "Yes") if(!client) return 1 - var/mob/observer/dead/observer = new() + + //Make a new mannequin quickly, and allow the observer to take the appearance + var/mob/living/carbon/human/dummy/mannequin = new() + client.prefs.dress_preview_mob(mannequin) + var/mob/observer/dead/observer = new(mannequin) + observer.forceMove(null) //Let's not stay in our doomed mannequin + qdel(mannequin) spawning = 1 src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo @@ -125,20 +131,13 @@ close_spawn_windows() var/obj/O = locate("landmark*Observer-Start") if(istype(O)) - src << "Now teleporting." - observer.loc = O.loc + to_chat(src,"Now teleporting.") + observer.forceMove(O.loc) else - src << "Could not locate an observer spawn point. Use the Teleport verb to jump to the station map." + to_chat(src,"Could not locate an observer spawn point. Use the Teleport verb to jump to the station map.") observer.timeofdeath = world.time // Set the time of death so that the respawn timer works correctly. announce_ghost_joinleave(src) - var/mob/living/carbon/human/dummy/mannequin = new() - client.prefs.dress_preview_mob(mannequin) - observer.appearance = mannequin - observer.alpha = 127 - observer.layer = initial(observer.layer) - observer.invisibility = initial(observer.invisibility) - qdel(mannequin) if(client.prefs.be_random_name) client.prefs.real_name = random_name(client.prefs.identifying_gender) From 437d1d20cbcca2f0861ea1b53f6c24559e4118f6 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 14:51:30 -0400 Subject: [PATCH 51/74] POLARIS: Fixes #3270 (VS) - Cleanbots make noise too often, reduce chance --- code/modules/mob/living/bot/cleanbot.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index 4f9f81156f1..241993423d1 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -20,7 +20,7 @@ get_targets() /mob/living/bot/cleanbot/handleIdle() - if(!screwloose && !oddbutton && prob(5)) + if(!screwloose && !oddbutton && prob(2)) custom_emote(2, "makes an excited booping sound!") playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0) @@ -67,7 +67,8 @@ return busy = 1 - custom_emote(2, "begins to clean up \the [D]") + if(prob(20)) + custom_emote(2, "begins to clean up \the [D]") update_icons() var/cleantime = istype(D, /obj/effect/decal/cleanable/dirt) ? 10 : 50 if(do_after(src, cleantime)) From 657e98f11cc91f05b351d08813d24ccf086077bf Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 14:58:00 -0400 Subject: [PATCH 52/74] POLARIS: Fixes #3264 (VS) - MMI insertion sanitizes w/o numbers allowed --- code/modules/surgery/robotics.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 3174bbf405b..4debf4017c4 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -464,9 +464,9 @@ while(!new_name) if(!target) return var/try_name = input(target,"Pick a name for your new form!", "New Name", target.name) - var/clean_name = sanitizeName(try_name) + var/clean_name = sanitizeName(try_name, allow_numbers = TRUE) if(clean_name) - var/okay = alert(target,"New name will be '[clean_name]', ok?", "Cancel", "Ok") + var/okay = alert(target,"New name will be '[clean_name]', ok?", "Confirmation","Cancel","Ok") if(okay == "Ok") new_name = clean_name From 3158e529b4bf2da6c1f3b30bc5099692f3c1b3cf Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 15:51:28 -0400 Subject: [PATCH 53/74] POLARIS: Fixes #3237 (VS) - Cryoconsoles are lit even when unpowered --- code/game/machinery/cryopod.dm | 13 +++++++------ icons/obj/robot_storage.dmi | Bin 5166 -> 5948 bytes 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 89042fb5e18..5d6d7abdcc2 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -27,6 +27,13 @@ var/storage_name = "Cryogenic Oversight Control" var/allow_items = 1 +/obj/machinery/computer/cryopod/update_icon() + ..() + if((stat & NOPOWER) || (stat & BROKEN)) + icon_state = "[initial(icon_state)]-p" + else + icon_state = initial(icon_state) + /obj/machinery/computer/cryopod/robot name = "robotic storage console" desc = "An interface between crew and the robotic storage systems" @@ -41,8 +48,6 @@ /obj/machinery/computer/cryopod/dorms name = "residential oversight console" desc = "An interface between visitors and the residential oversight systems tasked with keeping track of all visitors in the deeper section of the colony." - icon = 'icons/obj/robot_storage.dmi' //placeholder - icon_state = "console" //placeholder circuit = "/obj/item/weapon/circuitboard/robotstoragecontrol" storage_type = "visitors" @@ -52,8 +57,6 @@ /obj/machinery/computer/cryopod/travel name = "docking oversight console" desc = "An interface between visitors and the docking oversight systems tasked with keeping track of all visitors who enter or exit from the docks." - icon = 'icons/obj/robot_storage.dmi' //placeholder - icon_state = "console" //placeholder circuit = "/obj/item/weapon/circuitboard/robotstoragecontrol" storage_type = "visitors" @@ -63,8 +66,6 @@ /obj/machinery/computer/cryopod/gateway name = "gateway oversight console" desc = "An interface between visitors and the gateway oversight systems tasked with keeping track of all visitors who enter or exit from the gateway." - icon = 'icons/obj/robot_storage.dmi' //placeholder - icon_state = "console" //placeholder circuit = "/obj/item/weapon/circuitboard/robotstoragecontrol" storage_type = "visitors" diff --git a/icons/obj/robot_storage.dmi b/icons/obj/robot_storage.dmi index 52b79d26603767b4f66b5fb4368a421bd6ecbb4c..24e0aa73a37c6ee2bc8337ca91d78cac101f38a7 100644 GIT binary patch literal 5948 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 FV1ge%@3;T} From 166d582a5b4e55d3915f7ebca11828df76524110 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 18:02:45 -0400 Subject: [PATCH 54/74] POLARIS: Fixes #3238 (VS) - Nothing but humans can understand silicons talking --- code/modules/mob/living/silicon/silicon.dm | 3 ++- code/modules/mob/living/voice/voice.dm | 7 ++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 0d88e0c96ff..602be39e879 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -30,7 +30,8 @@ /mob/living/silicon/New() silicon_mob_list |= src ..() - add_language("Galactic Common") + add_language(LANGUAGE_GALCOM) + set_default_language(all_languages[LANGUAGE_GALCOM]) init_id() init_subsystems() diff --git a/code/modules/mob/living/voice/voice.dm b/code/modules/mob/living/voice/voice.dm index 3bc7929eacb..68ac2da7584 100644 --- a/code/modules/mob/living/voice/voice.dm +++ b/code/modules/mob/living/voice/voice.dm @@ -8,11 +8,8 @@ emote_type = 2 //This lets them emote through containers. The communicator has a image feed of the person calling them so... /mob/living/voice/New(loc) - add_language("Galactic Common") - for(var/datum/language/L in languages) //This is needed to get around some saycode problems. - if(L.name == "Galactic Common") - set_default_language(L) - break + add_language(LANGUAGE_GALCOM) + set_default_language(all_languages[LANGUAGE_GALCOM]) if(istype(loc, /obj/item/device/communicator)) comm = loc From f4e5aefebf65bb23c3623df1c5ed86ac0886cd28 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 18:07:44 -0400 Subject: [PATCH 55/74] POLARIS: Fixes #3221 (VS) - No explanation of what to do in the case of system instability --- code/modules/mob/living/carbon/human/human_powers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index af9e46f3512..67934042561 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -167,7 +167,7 @@ var/toxDam = getToxLoss() if(toxDam) - output += "System Instability: [toxDam > 25 ? "Severe" : "Moderate"]\n" + output += "System Instability: [toxDam > 25 ? "Severe" : "Moderate"]. Seek charging station for cleanup.\n" else output += "System Instability: OK\n" From 679b3900073ef780940838e593e5e9d4325f1764 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 18:38:56 -0400 Subject: [PATCH 56/74] POLARIS: Fixes #2601 (VS) - Allows mechs to continue charging after battery swap w/o moving --- code/game/mecha/mech_bay.dm | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index 55255d20974..5584590f920 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -52,22 +52,21 @@ if(charging.loc != src.loc) // Could be qdel or teleport or something stop_charging() return - var/done = 1 - if(charging.cell) + var/done = FALSE + if(charging.cell) var/t = min(charge, charging.cell.maxcharge - charging.cell.charge) if(t > 0) charging.give_power(t) use_power(t * 150) - done = 0 else charging.occupant_message("Fully charged.") + done = TRUE if(repair && charging.health < initial(charging.health)) charging.health = min(charging.health + repair, initial(charging.health)) if(charging.health == initial(charging.health)) charging.occupant_message("Fully repaired.") - else - done = 0 + done = FALSE if(done) stop_charging() return From 29eb468ef502fd9335a7fc0a57338ed2e89a5a02 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 19:01:36 -0400 Subject: [PATCH 57/74] POLARIS: Fixes #5282 (VS) - Allow use of pens to label pill bottles, like glass bottles --- .../objects/items/weapons/storage/firstaid.dm | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index 53e73a66e21..9c4a44d76d7 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -173,6 +173,43 @@ max_storage_space = ITEMSIZE_COST_TINY * 14 max_w_class = ITEMSIZE_TINY + var/label_text = "" + var/base_name = " " + var/base_desc = " " + +/obj/item/weapon/storage/pill_bottle/New() + ..() + base_name = name + base_desc = desc + +/obj/item/weapon/storage/pill_bottle/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen)) + var/tmp_label = sanitizeSafe(input(user, "Enter a label for [name]", "Label", label_text), MAX_NAME_LEN) + if(length(tmp_label) > 50) + to_chat(user, "The label can be at most 50 characters long.") + else if(length(tmp_label) > 10) + to_chat(user, "You set the label.") + label_text = tmp_label + update_name_label() + else + to_chat(user, "You set the label to \"[tmp_label]\".") + label_text = tmp_label + update_name_label() + else + ..() + +/obj/item/weapon/storage/pill_bottle/proc/update_name_label() + if(!label_text) + name = base_name + desc = base_desc + return + else if(length(label_text) > 10) + var/short_label_text = copytext(label_text, 1, 11) + name = "[base_name] ([short_label_text]...)" + else + name = "[base_name] ([label_text])" + desc = "[base_desc] It is labeled \"[label_text]\"." + /obj/item/weapon/storage/pill_bottle/antitox name = "bottle of Dylovene pills" desc = "Contains pills used to counter toxins." From a3fb959d988710378a54cabda87ad4bf299683b8 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Tue, 20 Mar 2018 19:02:29 -0400 Subject: [PATCH 58/74] POLARIS: Fixes #2573 (VS) - Slap cigarettes off people's faces --- code/modules/mob/living/carbon/human/emote.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 0a85e9a155c..09b7aadc70d 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -644,6 +644,10 @@ if(M) message = "slaps [M] across the face. Ouch!" playsound(loc, 'sound/effects/snap.ogg', 50, 1) + if(ishuman(M)) //Snowflakey! + var/mob/living/carbon/human/H = M + if(istype(H.wear_mask,/obj/item/clothing/mask/smokable)) + H.drop_from_inventory(H.wear_mask) else message = "slaps [T.himself]!" playsound(loc, 'sound/effects/snap.ogg', 50, 1) From e14857b16915fc594da1e04c2027baa4cc1baa6b Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Mon, 19 Mar 2018 23:01:00 -0400 Subject: [PATCH 59/74] POLARIS: Ventcrawling assistance --- code/_onclick/hud/hud.dm | 8 ++++++++ code/modules/ventcrawl/ventcrawl.dm | 4 ++++ icons/mob/screen1.dmi | Bin 167008 -> 167147 bytes 3 files changed, 12 insertions(+) diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 3a251f71fad..f015976c32d 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -9,6 +9,7 @@ var/list/global_huds = list( global_hud.whitense, global_hud.vimpaired, global_hud.darkMask, + global_hud.centermarker, global_hud.nvg, global_hud.thermal, global_hud.meson, @@ -27,6 +28,7 @@ var/list/global_huds = list( var/obj/screen/whitense var/list/vimpaired var/list/darkMask + var/obj/screen/centermarker var/obj/screen/darksight var/obj/screen/nvg var/obj/screen/thermal @@ -72,6 +74,12 @@ var/list/global_huds = list( darksight.plane = PLANE_LIGHTING darksight.plane = LIGHTING_LAYER + 0.1 + //Marks the center of the screen, for things like ventcrawl + centermarker = new /obj/screen() + centermarker.icon = 'icons/mob/screen1.dmi' + centermarker.icon_state = "centermarker" + centermarker.screen_loc = "CENTER,CENTER" + nvg = setup_overlay("nvg_hud") thermal = setup_overlay("thermal_hud") meson = setup_overlay("meson_hud") diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index 4741038cf4b..3a382c1c944 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -35,6 +35,7 @@ var/list/ventcrawl_machinery = list( if(is_ventcrawling && istype(loc, /obj/machinery/atmospherics)) //attach us back into the pipes remove_ventcrawl() add_ventcrawl(loc) + client.screen += global_hud.centermarker /mob/living/simple_animal/slime/can_ventcrawl() if(victim) @@ -182,6 +183,8 @@ var/list/ventcrawl_machinery = list( A.pipe_image = image(A, A.loc, layer = 20, dir = A.dir) pipes_shown += A.pipe_image client.images += A.pipe_image + if(client) + client.screen += global_hud.centermarker /mob/living/proc/remove_ventcrawl() is_ventcrawling = 0 @@ -189,6 +192,7 @@ var/list/ventcrawl_machinery = list( if(client) for(var/image/current_image in pipes_shown) client.images -= current_image + client.screen -= global_hud.centermarker client.eye = src pipes_shown.len = 0 \ No newline at end of file diff --git a/icons/mob/screen1.dmi b/icons/mob/screen1.dmi index 6828c365eac9b5b21db74325aa3f7136170dab5e..0798bbc4d3c6377a785b91e08d9241c5be82f118 100644 GIT binary patch delta 2088 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 avOov(7dQo5elGFT?++2a$JgwSz4<>>*3-8D From d738e99d2f33027db787880916298cc11cfc2c1c Mon Sep 17 00:00:00 2001 From: Leshana Date: Sun, 18 Mar 2018 20:12:47 -0400 Subject: [PATCH 60/74] POLARIS: Fix holders to avoid forcemoving held mob to nullspace --- code/modules/mob/holder.dm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index a1cfdcb39b6..973757df64f 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -39,10 +39,13 @@ var/list/holder_mob_icon_cache = list() update_state() /obj/item/weapon/holder/proc/update_state() - if(istype(loc,/turf) || !(contents.len)) + if(!(contents.len)) + qdel(src) + else if(isturf(loc)) + drop_items() if(held_mob) held_mob.forceMove(loc) - drop_items() + held_mob = null qdel(src) /obj/item/weapon/holder/proc/drop_items() From 3d4fe982778af9af35286b4d3b7dffaa85afdabc Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sun, 18 Mar 2018 18:18:28 -0400 Subject: [PATCH 61/74] POLARIS: Allow crawling through vertical pipes --- code/modules/multiz/movement.dm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm index caef5069345..42a501459f8 100644 --- a/code/modules/multiz/movement.dm +++ b/code/modules/multiz/movement.dm @@ -84,6 +84,16 @@ /mob/proc/can_ztravel() return 0 +/mob/living/zMove(direction) + //Sort of a lame hack to allow ztravel through zpipes. Should be improved. + if(is_ventcrawling && istype(loc,/obj/machinery/atmospherics/pipe/zpipe)) + var/obj/machinery/atmospherics/pipe/zpipe/currentpipe = loc + if(istype(currentpipe.node1,/obj/machinery/atmospherics/pipe/zpipe)) + currentpipe.ventcrawl_to(src, currentpipe.node1, direction) + else if(istype(currentpipe.node2,/obj/machinery/atmospherics/pipe/zpipe)) + currentpipe.ventcrawl_to(src, currentpipe.node2, direction) + return ..() + /mob/observer/can_ztravel() return 1 From 9f4a14b17151e66015d2838902f4c69dbf07ac87 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 17 Mar 2018 21:24:11 -0400 Subject: [PATCH 62/74] POLARIS: Weird snacks runtime --- code/modules/reagents/reagent_containers/food/snacks.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 18852a52dc1..3a7cec0213d 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -48,7 +48,7 @@ return /obj/item/weapon/reagent_containers/food/snacks/attack(mob/M as mob, mob/user as mob, def_zone) - if(!reagents.total_volume) + if(reagents && !reagents.total_volume) user << "None of [src] left!" user.drop_from_inventory(src) qdel(src) From ef904f453c854680607dd4a97736515a11bf4c1e Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 17 Mar 2018 21:27:46 -0400 Subject: [PATCH 63/74] POLARIS: Sometimes items have this set to null because they are bad. --- code/game/objects/items.dm | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index b5122f29ae6..748a203cc4d 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -727,14 +727,16 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. return icon_override //2: species-specific sprite sheets (skipped for inhands) - var/sheet = sprite_sheets[body_type] - if(sheet && !inhands) - return sheet + if(LAZYLEN(sprite_sheets)) + var/sheet = sprite_sheets[body_type] + if(sheet && !inhands) + return sheet //3: slot-specific sprite sheets - sheet = item_icons[slot_name] - if(sheet) - return sheet + if(LAZYLEN(item_icons)) + var/sheet = item_icons[slot_name] + if(sheet) + return sheet //4: item's default icon if(default_worn_icon) @@ -751,9 +753,10 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. /obj/item/proc/get_worn_icon_state(var/slot_name) //1: slot-specific sprite sheets - var/state = item_state_slots[slot_name] - if(state) - return state + if(LAZYLEN(item_state_slots)) + var/state = item_state_slots[slot_name] + if(state) + return state //2: item_state variable if(item_state) From e8258ff13f12d300ae883d5e185af2a7111adb62 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 17 Mar 2018 21:41:53 -0400 Subject: [PATCH 64/74] POLARIS: Beam weapons runtime when you shoot yourself --- code/modules/projectiles/projectile.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 32702881318..b398de7d2f0 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -401,7 +401,7 @@ P.activate() /obj/item/projectile/proc/impact_effect(var/matrix/M) - if(ispath(tracer_type)) + if(ispath(tracer_type) && location) var/obj/effect/projectile/P = new impact_type(location.loc) if(istype(P)) From f7d79855a0bf68fed650f9cbaaa01984dd9f69fa Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 17 Mar 2018 14:58:36 -0400 Subject: [PATCH 65/74] POLARIS: Fix a call to the wrong update icons in prom regen --- code/modules/mob/living/carbon/human/human_powers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 67934042561..471841049da 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -273,7 +273,7 @@ var/obj/item/organ/O = new limb_path(src) organ_data["descriptor"] = O.name to_chat(src, "You feel a slithering sensation as your [O.name] reform.") - update_icons_all() + update_icons_body() active_regen = FALSE else to_chat(src, "Your regeneration is interrupted!") From 7cac2052b575f8e9ba3d7eb821871eb010c0d99d Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Fri, 16 Mar 2018 19:51:46 -0400 Subject: [PATCH 66/74] POLARIS: Fix incorrect robolimb checks --- code/game/machinery/adv_med.dm | 4 ++-- code/game/machinery/kitchen/cooking_machines/fryer.dm | 4 ++-- code/modules/mob/living/bot/farmbot.dm | 2 +- code/modules/mob/living/bot/medbot.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 5 ++++- code/modules/mob/living/carbon/human/human_defense.dm | 2 +- code/modules/virus2/effect.dm | 4 ++-- 7 files changed, 13 insertions(+), 10 deletions(-) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 2d80766ea66..c3251ce1555 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -343,7 +343,7 @@ organStatus["destroyed"] = 1 if(E.status & ORGAN_BROKEN) organStatus["broken"] = E.broken_description - if(E.status & ORGAN_ROBOT) + if(E.robotic >= ORGAN_ROBOT) organStatus["robotic"] = 1 if(E.splinted) organStatus["splinted"] = 1 @@ -512,7 +512,7 @@ bled = "Bleeding:" if(e.status & ORGAN_BROKEN) AN = "[e.broken_description]:" - if(e.status & ORGAN_ROBOT) + if(e.robotic >= ORGAN_ROBOT) robot = "Prosthetic:" if(e.status & ORGAN_DEAD) o_dead = "Necrotic:" diff --git a/code/game/machinery/kitchen/cooking_machines/fryer.dm b/code/game/machinery/kitchen/cooking_machines/fryer.dm index 7e5cc055e85..451f84c2ff9 100644 --- a/code/game/machinery/kitchen/cooking_machines/fryer.dm +++ b/code/game/machinery/kitchen/cooking_machines/fryer.dm @@ -36,7 +36,7 @@ if(H.species.flags & NO_PAIN) nopain = 2 E = H.get_organ(user.zone_sel.selecting) - if(E.status & ORGAN_ROBOT) + if(E.robotic >= ORGAN_ROBOT) nopain = 1 user.visible_message("\The [user] shoves \the [victim][E ? "'s [E.name]" : ""] into \the [src]!") @@ -45,7 +45,7 @@ E.take_damage(0, rand(20,30)) if(E.children && E.children.len) for(var/obj/item/organ/external/child in E.children) - if(nopain && nopain < 2 && !(child.status & ORGAN_ROBOT)) + if(nopain && nopain < 2 && !(child.robotic >= ORGAN_ROBOT)) nopain = 0 child.take_damage(0, rand(20,30)) else diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm index 1e23af341c3..0141cdb39a5 100644 --- a/code/modules/mob/living/bot/farmbot.dm +++ b/code/modules/mob/living/bot/farmbot.dm @@ -338,7 +338,7 @@ new /obj/item/weapon/farmbot_arm_assembly(loc, src) /obj/structure/reagent_dispensers/watertank/attackby(var/obj/item/organ/external/S, mob/user as mob) - if ((!istype(S, /obj/item/organ/external/arm)) || (!S.robotic == ORGAN_ROBOT)) + if ((!istype(S, /obj/item/organ/external/arm)) || S.robotic != ORGAN_ROBOT) ..() return diff --git a/code/modules/mob/living/bot/medbot.dm b/code/modules/mob/living/bot/medbot.dm index 29e9cd0a9b1..0e35d6b2b00 100644 --- a/code/modules/mob/living/bot/medbot.dm +++ b/code/modules/mob/living/bot/medbot.dm @@ -333,7 +333,7 @@ qdel(src) /obj/item/weapon/storage/firstaid/attackby(var/obj/item/organ/external/S, mob/user as mob) - if (!istype(S, /obj/item/organ/external/arm) || !(S.robotic == ORGAN_ROBOT)) + if (!istype(S, /obj/item/organ/external/arm) || S.robotic != ORGAN_ROBOT) ..() return diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index d2bf097d71e..c55ebee9eff 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1272,9 +1272,12 @@ if(!affecting) . = 0 fail_msg = "They are missing that limb." - else if (affecting.robotic >= ORGAN_ROBOT) + else if (affecting.robotic == ORGAN_ROBOT) . = 0 fail_msg = "That limb is robotic." + else if (affecting.robotic >= ORGAN_LIFELIKE) + . = 0 + fail_msg = "Your needle refuses to penetrate more than a short distance..." else switch(target_zone) if(BP_HEAD) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 1befd9579b3..db20f7f7440 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -341,7 +341,7 @@ emp_act /mob/living/carbon/human/emag_act(var/remaining_charges, mob/user, var/emag_source) var/obj/item/organ/external/affecting = get_organ(user.zone_sel.selecting) - if(!affecting || !(affecting.status & ORGAN_ROBOT)) + if(!affecting || !(affecting.robotic >= ORGAN_ROBOT)) user << "That limb isn't robotic." return -1 if(affecting.sabotaged) diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index 838ea5f0edd..d7db2633ad5 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -190,7 +190,7 @@ var/mob/living/carbon/human/H = mob var/organ = pick(list("heart","kidney","liver", "lungs")) var/obj/item/organ/internal/O = H.organs_by_name[organ] - if (!(O.robotic = ORGAN_ROBOT)) + if (O.robotic != ORGAN_ROBOT) O.damage += (5*multiplier) H << "You feel a cramp in your guts." @@ -370,7 +370,7 @@ var/mob/living/carbon/human/H = mob var/obj/item/organ/internal/O = H.organs_by_name for (var/organ in H.organs_by_name) - if (!(O.robotic = ORGAN_ROBOT)) + if (O.robotic != ORGAN_ROBOT) O.rejecting = 0 From 90129587245c7e76c51acdbd73e319d427af0ba0 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Fri, 16 Mar 2018 00:19:12 -0400 Subject: [PATCH 67/74] POLARIS: Heal robolimbs when you heal everything Typically only used in magic and stuff, makes sense to heal both (otherwise there's no way to heal whole FBP bodies) --- .../mob/living/carbon/human/human_damage.dm | 15 +++++++++------ code/modules/mob/living/living.dm | 6 ++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 45532aa1d48..95a3d0e5ed6 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -108,7 +108,8 @@ amount += O.burn_dam return amount -/mob/living/carbon/human/adjustBruteLoss(var/amount) +//'include_robo' only applies to healing, for legacy purposes, as all damage typically hurts both types of organs +/mob/living/carbon/human/adjustBruteLoss(var/amount,var/include_robo) amount = amount*species.brute_mod if(amount > 0) for(var/datum/modifier/M in modifiers) @@ -121,10 +122,11 @@ for(var/datum/modifier/M in modifiers) if(!isnull(M.incoming_healing_percent)) amount *= M.incoming_healing_percent - heal_overall_damage(-amount, 0) + heal_overall_damage(-amount, 0, include_robo) BITSET(hud_updateflag, HEALTH_HUD) -/mob/living/carbon/human/adjustFireLoss(var/amount) +//'include_robo' only applies to healing, for legacy purposes, as all damage typically hurts both types of organs +/mob/living/carbon/human/adjustFireLoss(var/amount,var/include_robo) amount = amount*species.burn_mod if(amount > 0) for(var/datum/modifier/M in modifiers) @@ -137,7 +139,7 @@ for(var/datum/modifier/M in modifiers) if(!isnull(M.incoming_healing_percent)) amount *= M.incoming_healing_percent - heal_overall_damage(0, -amount) + heal_overall_damage(0, -amount, include_robo) BITSET(hud_updateflag, HEALTH_HUD) /mob/living/carbon/human/proc/adjustBruteLossByPart(var/amount, var/organ_name, var/obj/damage_source = null) @@ -348,7 +350,8 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t //Heal MANY external organs, in random order -/mob/living/carbon/human/heal_overall_damage(var/brute, var/burn) +//'include_robo' only applies to healing, for legacy purposes, as all damage typically hurts both types of organs +/mob/living/carbon/human/heal_overall_damage(var/brute, var/burn, var/include_robo) var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn) var/update = 0 @@ -358,7 +361,7 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t var/brute_was = picked.brute_dam var/burn_was = picked.burn_dam - update |= picked.heal_damage(brute,burn) + update |= picked.heal_damage(brute,burn,robo_repair = include_robo) brute -= (brute_was-picked.brute_dam) burn -= (burn_was-picked.burn_dam) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index e1c44ae9a53..21298e94db9 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -254,7 +254,8 @@ default behaviour is: /mob/living/proc/getActualBruteLoss() // Mostly for humans with robolimbs. return getBruteLoss() -/mob/living/proc/adjustBruteLoss(var/amount) +//'include_robo' only applies to healing, for legacy purposes, as all damage typically hurts both types of organs +/mob/living/proc/adjustBruteLoss(var/amount,var/include_robo) if(status_flags & GODMODE) return 0 //godmode if(amount > 0) @@ -328,7 +329,8 @@ default behaviour is: /mob/living/proc/getActualFireLoss() // Mostly for humans with robolimbs. return getFireLoss() -/mob/living/proc/adjustFireLoss(var/amount) +//'include_robo' only applies to healing, for legacy purposes, as all damage typically hurts both types of organs +/mob/living/proc/adjustFireLoss(var/amount,var/include_robo) if(status_flags & GODMODE) return 0 //godmode if(amount > 0) for(var/datum/modifier/M in modifiers) From 6072077d10abcad875b93d90554691e6c47b97f3 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Fri, 16 Mar 2018 19:53:26 -0400 Subject: [PATCH 68/74] POLARIS: Add eye color to shapeshifters --- .../human/species/species_shapeshift.dm | 37 ++++++++++++++++++- .../human/species/station/prometheans.dm | 1 + .../mob/living/carbon/human/update_icons.dm | 2 +- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species/species_shapeshift.dm b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm index c8e3e0c5d5a..0dd73b3f887 100644 --- a/code/modules/mob/living/carbon/human/species/species_shapeshift.dm +++ b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm @@ -183,6 +183,9 @@ var/list/wrapped_species_by_ref = list() r_skin = hex2num(copytext(new_skin, 2, 4)) g_skin = hex2num(copytext(new_skin, 4, 6)) b_skin = hex2num(copytext(new_skin, 6, 8)) + r_synth = r_skin + g_synth = g_skin + b_synth = b_skin var/datum/species/shapeshifter/S = species if(S.monochromatic) @@ -286,4 +289,36 @@ var/list/wrapped_species_by_ref = list() if(species && mind) apply_traits() - return \ No newline at end of file + return + +/mob/living/carbon/human/proc/shapeshifter_select_eye_colour() + + set name = "Select Eye Color" + set category = "Abilities" + + if(stat || world.time < last_special) + return + + last_special = world.time + 50 + + var/current_color = rgb(r_eyes,g_eyes,b_eyes) + var/new_eyes = input("Pick a new color for your eyes.","Eye Color", current_color) as null|color + if(!new_eyes) + return + + shapeshifter_set_eye_color(new_eyes) + +/mob/living/carbon/human/proc/shapeshifter_set_eye_color(var/new_eyes) + + var/list/new_color_rgb_list = hex2rgb(new_eyes) + // First, update mob vars. + r_eyes = new_color_rgb_list[1] + g_eyes = new_color_rgb_list[2] + b_eyes = new_color_rgb_list[3] + // Now sync the organ's eye_colour list, if possible + var/obj/item/organ/internal/eyes/eyes = internal_organs_by_name[O_EYES] + if(istype(eyes)) + eyes.update_colour() + + update_icons_body() + update_eyes() diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm index 800d15c6d4f..00f7973202c 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -83,6 +83,7 @@ var/datum/species/shapeshifter/promethean/prometheans /mob/living/carbon/human/proc/shapeshifter_select_shape, /mob/living/carbon/human/proc/shapeshifter_select_colour, /mob/living/carbon/human/proc/shapeshifter_select_hair, + /mob/living/carbon/human/proc/shapeshifter_select_eye_colour, /mob/living/carbon/human/proc/shapeshifter_select_hair_colors, /mob/living/carbon/human/proc/shapeshifter_select_gender, /mob/living/carbon/human/proc/regenerate diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 5c10ea509e0..71717886f8b 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -231,7 +231,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() if(eyes) icon_key += "[rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3])]" else - icon_key += "#000000" + icon_key += "[r_eyes], [g_eyes], [b_eyes]" for(var/organ_tag in species.has_limbs) var/obj/item/organ/external/part = organs_by_name[organ_tag] From f6321228a07cadc89b9c785ac681bb4ff5093dc3 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Thu, 15 Mar 2018 23:50:14 -0400 Subject: [PATCH 69/74] POLARIS: Adds an animation thing, uses it on ventcrawls --- code/modules/mob/animations.dm | 36 +++++++++++++++++++++++++++++ code/modules/ventcrawl/ventcrawl.dm | 1 + 2 files changed, 37 insertions(+) diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm index edffbb5a874..7f082e1ef08 100644 --- a/code/modules/mob/animations.dm +++ b/code/modules/mob/animations.dm @@ -140,6 +140,42 @@ note dizziness decrements automatically in the mob's Life() proc. //reset the pixel offsets to zero is_floating = 0 +/atom/movable/proc/fade_towards(atom/A,var/time = 2) + set waitfor = FALSE + + var/pixel_x_diff = 0 + var/pixel_y_diff = 0 + var/pixel_z_diff = 0 + var/direction = get_dir(src, A) + if(direction & NORTH) + pixel_y_diff = 32 + else if(direction & SOUTH) + pixel_y_diff = -32 + + if(direction & EAST) + pixel_x_diff = 32 + else if(direction & WEST) + pixel_x_diff = -32 + + if(!direction) // On top of? + pixel_z_diff = -8 + + var/default_pixel_x = initial(pixel_x) + var/default_pixel_y = initial(pixel_y) + var/default_pixel_z = initial(pixel_z) + var/initial_alpha = alpha + var/mob/mob = src + if(istype(mob)) + default_pixel_x = mob.default_pixel_x + default_pixel_y = mob.default_pixel_y + + animate(src, alpha = 0, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, pixel_z = pixel_z + pixel_z_diff, time = time) + sleep(time+1) //So you can wait on this proc to finish if you want to time your next steps + pixel_x = default_pixel_x + pixel_y = default_pixel_y + pixel_z = default_pixel_z + alpha = initial_alpha + /atom/movable/proc/do_attack_animation(atom/A) var/pixel_x_diff = 0 diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index 3a382c1c944..e4a402188a3 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -155,6 +155,7 @@ var/list/ventcrawl_machinery = list( if(HAZARD_HIGH_PRESSURE to INFINITY) to_chat(src, "You feel a roaring wind pushing you away from the vent!") + fade_towards(vent_found,45) if(!do_after(src, 45, vent_found, 1, 1)) return if(!can_ventcrawl()) From 3de715ef55b5d84e8f92deade6b33967c82ccd80 Mon Sep 17 00:00:00 2001 From: Neerti Date: Mon, 26 Mar 2018 00:41:55 -0400 Subject: [PATCH 70/74] Fixes Suit Storage Icons Items in suit storage should no longer vanish. --- code/__defines/items_clothing.dm | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm index 8f67815583e..637b450df67 100644 --- a/code/__defines/items_clothing.dm +++ b/code/__defines/items_clothing.dm @@ -88,17 +88,17 @@ #define slot_back 3 #define slot_belt 4 #define slot_wear_id 5 -#define slot_l_store 6 -#define slot_r_store 7 //Some things may reference this, try to keep it here +#define slot_s_store 6 +#define slot_l_store 7 +#define slot_r_store 8 //Some things may reference this, try to keep it here //Shown when inventory unhidden -#define slot_glasses 8 -#define slot_wear_mask 9 -#define slot_gloves 10 -#define slot_head 11 -#define slot_shoes 12 -#define slot_wear_suit 13 -#define slot_w_uniform 14 -#define slot_s_store 15 +#define slot_glasses 9 +#define slot_wear_mask 10 +#define slot_gloves 11 +#define slot_head 12 +#define slot_shoes 13 +#define slot_wear_suit 14 +#define slot_w_uniform 15 #define slot_l_ear 16 #define slot_r_ear 17 //Secret slots From a2841ce9d60c31f48c1c4f420a13bb7d456207a7 Mon Sep 17 00:00:00 2001 From: Atermonera Date: Wed, 28 Mar 2018 12:53:50 -0700 Subject: [PATCH 71/74] Nanoui now supports use of multiple templates (#5105) * Nanoui now supports use of multiple templates * Removing debug code, indentation * Indentation --- code/modules/nano/nanoui.dm | 5 ++ nano/js/nano_state.js | 152 ++++++++++++++++---------------- nano/js/nano_template.js | 171 +++++++++++++++++++----------------- 3 files changed, 168 insertions(+), 160 deletions(-) diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index ec003a813e5..310bbfa9c52 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -519,3 +519,8 @@ nanoui is used to open and update nano browser uis */ /datum/nanoui/proc/update(var/force_open = 0) src_object.ui_interact(user, ui_key, src, force_open, master_ui, state) + +/datum/nanoui/proc/append_template(var/key, var/filename) + add_template(key, filename) + open() + update(1) diff --git a/nano/js/nano_state.js b/nano/js/nano_state.js index 3e9ef3ab1ff..e211895cee5 100644 --- a/nano/js/nano_state.js +++ b/nano/js/nano_state.js @@ -7,8 +7,7 @@ function NanoStateClass() { return; } - this.key = this.key.toLowerCase(); - + this.key = this.key.toLowerCase(); NanoStateManager.addState(this);*/ } @@ -18,102 +17,99 @@ NanoStateClass.prototype.contentRendered = false; NanoStateClass.prototype.mapInitialised = false; NanoStateClass.prototype.isCurrent = function () { - return NanoStateManager.getCurrentState() == this; + return NanoStateManager.getCurrentState() == this; }; NanoStateClass.prototype.onAdd = function (previousState) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - NanoBaseCallbacks.addCallbacks(); - NanoBaseHelpers.addHelpers(); + // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function + NanoBaseCallbacks.addCallbacks(); + NanoBaseHelpers.addHelpers(); }; NanoStateClass.prototype.onRemove = function (nextState) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - NanoBaseCallbacks.removeCallbacks(); - NanoBaseHelpers.removeHelpers(); + // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function + NanoBaseCallbacks.removeCallbacks(); + NanoBaseHelpers.removeHelpers(); }; NanoStateClass.prototype.onBeforeUpdate = function (data) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - data = NanoStateManager.executeBeforeUpdateCallbacks(data); - - return data; // Return data to continue, return false to prevent onUpdate and onAfterUpdate + // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function + data = NanoStateManager.executeBeforeUpdateCallbacks(data); + return data; // Return data to continue, return false to prevent onUpdate and onAfterUpdate }; NanoStateClass.prototype.onUpdate = function (data) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function + // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function + try + { + if (!this.layoutRendered || (data['config'].hasOwnProperty('autoUpdateLayout') && data['config']['autoUpdateLayout'])) + { + $("#uiLayout").html(NanoTemplate.parse('layout', data)); // render the 'mail' template to the #mainTemplate div + this.layoutRendered = true; + } + if (!this.contentRendered || (data['config'].hasOwnProperty('autoUpdateContent') && data['config']['autoUpdateContent'])) + { + var content = ""; + var keys = NanoTemplate.getKeys(); + for (i = 0; i < keys.length; i++) { + if(keys[i] == "layout"){ continue; } + content += NanoTemplate.parse(keys[i], data); + } + $("#uiContent").html(content); // render the 'mail' template to the #mainTemplate div + this.contentRendered = true; + } + if (NanoTemplate.templateExists('mapContent')) + { + if (!this.mapInitialised) + { + // Add drag functionality to the map ui + $('#uiMap').draggable(); + $('#uiMapTooltip') + .off('click') + .on('click', function (event) { + event.preventDefault(); + $(this).fadeOut(400); + }); + this.mapInitialised = true; + } - try - { - if (!this.layoutRendered || (data['config'].hasOwnProperty('autoUpdateLayout') && data['config']['autoUpdateLayout'])) - { - $("#uiLayout").html(NanoTemplate.parse('layout', data)); // render the 'mail' template to the #mainTemplate div - this.layoutRendered = true; - } - if (!this.contentRendered || (data['config'].hasOwnProperty('autoUpdateContent') && data['config']['autoUpdateContent'])) - { - $("#uiContent").html(NanoTemplate.parse('main', data)); // render the 'mail' template to the #mainTemplate div - this.contentRendered = true; - } - if (NanoTemplate.templateExists('mapContent')) - { - if (!this.mapInitialised) - { - // Add drag functionality to the map ui - $('#uiMap').draggable(); + $("#uiMapContent").html(NanoTemplate.parse('mapContent', data)); // render the 'mapContent' template to the #uiMapContent div - $('#uiMapTooltip') - .off('click') - .on('click', function (event) { - event.preventDefault(); - $(this).fadeOut(400); - }); - - this.mapInitialised = true; - } - - $("#uiMapContent").html(NanoTemplate.parse('mapContent', data)); // render the 'mapContent' template to the #uiMapContent div - - if (data['config'].hasOwnProperty('showMap') && data['config']['showMap']) - { - $('#uiContent').addClass('hidden'); - $('#uiMapWrapper').removeClass('hidden'); - } - else - { - $('#uiMapWrapper').addClass('hidden'); - $('#uiContent').removeClass('hidden'); - } - } - if (NanoTemplate.templateExists('mapHeader')) - { - $("#uiMapHeader").html(NanoTemplate.parse('mapHeader', data)); // render the 'mapHeader' template to the #uiMapHeader div - } - if (NanoTemplate.templateExists('mapFooter')) - { - $("#uiMapFooter").html(NanoTemplate.parse('mapFooter', data)); // render the 'mapFooter' template to the #uiMapFooter div - } - } - catch(error) - { - alert('ERROR: An error occurred while rendering the UI: ' + error.message); - return; - } + if (data['config'].hasOwnProperty('showMap') && data['config']['showMap']) + { + $('#uiContent').addClass('hidden'); + $('#uiMapWrapper').removeClass('hidden'); + } + else + { + $('#uiMapWrapper').addClass('hidden'); + $('#uiContent').removeClass('hidden'); + } + } + if (NanoTemplate.templateExists('mapHeader')) + { + $("#uiMapHeader").html(NanoTemplate.parse('mapHeader', data)); // render the 'mapHeader' template to the #uiMapHeader div + } + if (NanoTemplate.templateExists('mapFooter')) + { + $("#uiMapFooter").html(NanoTemplate.parse('mapFooter', data)); // render the 'mapFooter' template to the #uiMapFooter div + } + } + catch(error) + { + alert('ERROR: An error occurred while rendering the UI: ' + error.message); + return; + } }; NanoStateClass.prototype.onAfterUpdate = function (data) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - NanoStateManager.executeAfterUpdateCallbacks(data); + // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function + NanoStateManager.executeAfterUpdateCallbacks(data); }; NanoStateClass.prototype.alertText = function (text) { - // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function - - alert(text); + // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function + alert(text); }; diff --git a/nano/js/nano_template.js b/nano/js/nano_template.js index f8f5d265948..b2f894fd076 100644 --- a/nano/js/nano_template.js +++ b/nano/js/nano_template.js @@ -1,15 +1,15 @@ var NanoTemplate = function () { - var _templateData = {}; + var _templateData = {}; - var _templates = {}; - var _compiledTemplates = {}; + var _templates = {}; + var _compiledTemplates = {}; var _helpers = {}; - var init = function () { - // We store templateData in the body tag, it's as good a place as any + var init = function () { + // We store templateData in the body tag, it's as good a place as any _templateData = $('body').data('templateData'); if (_templateData == null) @@ -18,94 +18,101 @@ var NanoTemplate = function () { } loadNextTemplate(); - }; + }; - var loadNextTemplate = function () { - // we count the number of templates for this ui so that we know when they've all been rendered - var templateCount = Object.size(_templateData); + var loadNextTemplate = function () { + // we count the number of templates for this ui so that we know when they've all been rendered + var templateCount = Object.size(_templateData); - if (!templateCount) - { - $(document).trigger('templatesLoaded'); - return; - } + if (!templateCount) + { + $(document).trigger('templatesLoaded'); + return; + } - // load markup for each template and register it - for (var key in _templateData) - { - if (!_templateData.hasOwnProperty(key)) - { - continue; - } + // load markup for each template and register it + for (var key in _templateData) + { + if (!_templateData.hasOwnProperty(key)) + { + continue; + } - $.when($.ajax({ - url: _templateData[key], - cache: false, - dataType: 'text' - })) - .done(function(templateMarkup) { + $.when($.ajax({ + url: _templateData[key], + cache: false, + dataType: 'text' + })) + .done(function(templateMarkup) { - templateMarkup += '
'; + templateMarkup += '
'; - try - { - NanoTemplate.addTemplate(key, templateMarkup); - } - catch(error) - { - alert('ERROR: An error occurred while loading the UI: ' + error.message); - return; - } + try + { + NanoTemplate.addTemplate(key, templateMarkup); + } + catch(error) + { + alert('ERROR: An error occurred while loading the UI: ' + error.message); + return; + } - delete _templateData[key]; + delete _templateData[key]; - loadNextTemplate(); - }) - .fail(function () { - alert('ERROR: Loading template ' + key + '(' + _templateData[key] + ') failed!'); - }); + loadNextTemplate(); + }) + .fail(function () { + alert('ERROR: Loading template ' + key + '(' + _templateData[key] + ') failed!'); + }); - return; - } - } + return; + } + } - var compileTemplates = function () { + var compileTemplates = function () { - for (var key in _templates) { - try { - _compiledTemplates[key] = doT.template(_templates[key], null, _templates) - } - catch (error) { - alert(error.message); - } - } - }; + for (var key in _templates) { + try { + _compiledTemplates[key] = doT.template(_templates[key], null, _templates) + } + catch (error) { + alert(error.message); + } + } + }; - return { - init: function () { - init(); - }, - addTemplate: function (key, templateString) { - _templates[key] = templateString; - }, - templateExists: function (key) { - return _templates.hasOwnProperty(key); - }, - parse: function (templateKey, data) { - if (!_compiledTemplates.hasOwnProperty(templateKey) || !_compiledTemplates[templateKey]) { - if (!_templates.hasOwnProperty(templateKey)) { - alert('ERROR: Template "' + templateKey + '" does not exist in _compiledTemplates!'); - return '

Template error (does not exist)

'; - } - compileTemplates(); - } - if (typeof _compiledTemplates[templateKey] != 'function') { - alert(_compiledTemplates[templateKey]); - alert('ERROR: Template "' + templateKey + '" failed to compile!'); - return '

Template error (failed to compile)

'; - } - return _compiledTemplates[templateKey].call(this, data['data'], data['config'], _helpers); - }, + return { + init: function () { + init(); + }, + addTemplate: function (key, templateString) { + _templates[key] = templateString; + }, + templateExists: function (key) { + return _templates.hasOwnProperty(key); + }, + getKeys: function () { + var _keys = []; + for(var key in _templates) { + _keys.push(key); + } + return _keys; + }, + parse: function (templateKey, data) { + if (!_compiledTemplates.hasOwnProperty(templateKey) || !_compiledTemplates[templateKey]) { + if (!_templates.hasOwnProperty(templateKey)) { + alert('ERROR: Template "' + templateKey + '" does not exist in _compiledTemplates!'); + return '

Templateerror (does not exist)

'; + } + compileTemplates(); + } + if (typeof _compiledTemplates[templateKey] != 'function') { + alert(_compiledTemplates[templateKey]); + alert('ERROR: Template "' + templateKey + '" failed to compile!'); + return '

Template error (failed to compile)

'; + } + return _compiledTemplates[templateKey].call(this, data['data'], data['config'], _helpers); + }, addHelper: function (helperName, helperFunction) { if (!jQuery.isFunction(helperFunction)) { alert('NanoTemplate.addHelper failed to add ' + helperName + ' as it is not a function.'); @@ -129,7 +136,7 @@ var NanoTemplate = function () { delete _helpers[helperName]; } } - } + } }(); From 7d3aec96fdbb62492b2341f667c0f7dd98a2aaa9 Mon Sep 17 00:00:00 2001 From: Aronai Sieyes Date: Wed, 28 Mar 2018 15:59:12 -0400 Subject: [PATCH 72/74] Arranges lots of things into planes (#5072) * Rearranges a billion things into planes * Make cryotubes fancy * Update Travis * Fix hiding logic --- .travis.yml | 4 +- code/ATMOSPHERICS/atmospherics.dm | 3 +- .../components/unary/outlet_injector.dm | 1 - code/ATMOSPHERICS/mainspipe.dm | 3 +- code/ATMOSPHERICS/pipes/cap.dm | 1 - code/__defines/_planes+layers.dm | 69 +++++++++++----- code/__defines/lighting.dm | 1 - code/__defines/mobs.dm | 2 +- code/_onclick/hud/alien_larva.dm | 2 +- code/_onclick/hud/hud.dm | 5 -- code/_onclick/hud/other_mobs.dm | 14 ++-- code/_onclick/hud/robot.dm | 12 +-- code/_onclick/telekinesis.dm | 2 +- code/controllers/Processes/planet.dm | 3 +- .../emergency_shuttle_controller.dm | 3 +- code/game/antagonist/antagonist_update.dm | 4 +- code/game/area/Space Station 13 areas.dm | 76 ------------------ code/game/area/areas.dm | 76 +++++++++++++++++- code/game/atoms.dm | 2 +- code/game/atoms_movable.dm | 2 +- .../endgame/supermatter_cascade/portal.dm | 5 +- code/game/machinery/Beacon.dm | 2 +- code/game/machinery/ai_slipper.dm | 1 - code/game/machinery/camera/camera.dm | 3 +- code/game/machinery/computer3/lapvend.dm | 1 - code/game/machinery/cryo.dm | 69 +++++++++------- code/game/machinery/holosign.dm | 2 +- code/game/machinery/kitchen/icecream.dm | 1 - code/game/machinery/kitchen/microwave.dm | 1 - code/game/machinery/kitchen/smartfridge.dm | 1 - code/game/machinery/machinery.dm | 1 + code/game/machinery/magnet.dm | 3 +- code/game/machinery/navbeacon.dm | 3 +- code/game/machinery/overview.dm | 4 +- code/game/machinery/vending.dm | 1 - code/game/mecha/combat/gorilla.dm | 2 +- code/game/mecha/mech_sensor.dm | 2 +- code/game/objects/effects/alien/aliens.dm | 5 +- code/game/objects/effects/chem/chemsmoke.dm | 2 +- .../objects/effects/decals/Cleanable/fuel.dm | 2 +- .../effects/decals/Cleanable/humans.dm | 4 +- .../objects/effects/decals/Cleanable/misc.dm | 15 +--- code/game/objects/effects/decals/cleanable.dm | 1 + code/game/objects/effects/decals/crayon.dm | 2 +- code/game/objects/effects/decals/misc.dm | 4 +- .../objects/effects/decals/warning_stripes.dm | 1 - code/game/objects/effects/misc.dm | 3 +- code/game/objects/effects/overlays.dm | 19 +++-- code/game/objects/effects/spiders.dm | 2 +- code/game/objects/items/shooting_range.dm | 1 - .../objects/items/weapons/id cards/cards.dm | 1 - code/game/objects/items/weapons/policetape.dm | 9 ++- code/game/objects/items/weapons/tape.dm | 2 +- code/game/objects/items/weapons/trays.dm | 2 +- code/game/objects/objs.dm | 2 + code/game/objects/structures/bedsheet_bin.dm | 7 +- code/game/objects/structures/girders.dm | 2 +- code/game/objects/structures/gravemarker.dm | 2 +- code/game/objects/structures/grille.dm | 2 +- code/game/objects/structures/lattice.dm | 2 +- code/game/objects/structures/morgue.dm | 2 +- code/game/objects/structures/railing.dm | 2 +- code/game/objects/structures/safe.dm | 3 +- code/game/objects/structures/signs.dm | 2 +- .../structures/stool_bed_chair_nest/chairs.dm | 6 +- code/game/objects/structures/target_stake.dm | 2 +- code/game/objects/structures/transit_tubes.dm | 2 +- code/game/objects/structures/window.dm | 4 +- code/game/supplyshuttle.dm | 3 +- code/game/turfs/flooring/flooring_decals.dm | 2 +- code/game/turfs/simulated/floor_icon.dm | 2 +- code/game/turfs/simulated/walls.dm | 2 +- code/game/turfs/turf.dm | 2 + code/game/turfs/unsimulated/shuttle.dm | 1 - code/modules/admin/admin.dm | 1 + code/modules/blob2/blobs/base_blob.dm | 3 +- code/modules/flufftext/Hallucination.dm | 2 +- .../hydroponics/spreading/spreading.dm | 5 +- code/modules/lighting/lighting_overlay.dm | 1 - code/modules/mob/dead/observer/observer.dm | 2 +- code/modules/mob/hear_say.dm | 5 -- code/modules/mob/holder.dm | 1 - .../living/carbon/alien/diona/diona_powers.dm | 2 - code/modules/mob/living/carbon/human/human.dm | 5 +- .../mob/living/carbon/human/human_powers.dm | 17 ---- .../carbon/human/species/station/seromi.dm | 2 +- .../mob/living/carbon/metroid/metroid.dm | 3 +- code/modules/mob/living/living.dm | 2 - code/modules/mob/living/living_powers.dm | 11 ++- code/modules/mob/living/say.dm | 7 +- .../mob/living/simple_animal/borer/borer.dm | 3 - .../simple_animal/borer/borer_powers.dm | 1 - code/modules/mob/mob_defines.dm | 3 +- code/modules/mob/mob_grab.dm | 7 +- code/modules/mob/mob_planes.dm | 1 - code/modules/paperwork/paper.dm | 3 +- code/modules/paperwork/paper_bundle.dm | 3 +- code/modules/power/fusion/core/core_field.dm | 3 +- .../fusion/fuel_assembly/fuel_assembly.dm | 1 - .../fusion/fuel_assembly/fuel_compressor.dm | 1 - code/modules/power/lighting.dm | 10 ++- code/modules/power/sensors/powernet_sensor.dm | 2 +- code/modules/power/singularity/singularity.dm | 2 +- code/modules/power/terminal.dm | 4 +- code/modules/projectiles/effects.dm | 2 +- code/modules/reagents/Chemistry-Machinery.dm | 1 - code/modules/recycling/conveyor2.dm | 3 +- code/modules/recycling/disposal.dm | 2 +- code/modules/shieldgen/energy_field.dm | 3 +- .../spells/aoe_turf/conjure/conjure.dm | 3 +- .../modules/spells/targeted/ethereal_jaunt.dm | 3 +- code/modules/tables/flipping.dm | 5 +- code/modules/tables/tables.dm | 2 +- code/modules/turbolift/turbolift_console.dm | 2 +- code/modules/ventcrawl/ventcrawl.dm | 3 +- .../xenoarcheaology/artifacts/gigadrill.dm | 2 +- icons/obj/cryogenics_split.dmi | Bin 5537 -> 3328 bytes maps/RandomZLevels/wildwest.dm | 3 +- 118 files changed, 336 insertions(+), 325 deletions(-) diff --git a/.travis.yml b/.travis.yml index c58b11584f8..754b84c3743 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,8 @@ sudo: false env: global: - - BYOND_MAJOR="511" - - BYOND_MINOR="1381" + - BYOND_MAJOR="512" + - BYOND_MINOR="1414" - MACRO_COUNT=4 matrix: - TEST_DEFINE="MAP_TEST" TEST_FILE="code/_map_tests.dm" RUN="0" diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 59163e1b82a..8e4ffc46ccd 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -17,7 +17,8 @@ Pipelines + Other Objects -> Pipe network var/nodealert = 0 var/power_rating //the maximum amount of power the machine can use to do work, affects how powerful the machine is, in Watts - layer = 2.4 //under wires with their 2.44 + layer = PIPES_LAYER + plane = PLATING_PLANE var/connect_types = CONNECT_TYPE_REGULAR var/icon_connect_type = "" //"-supply" or "-scrubbers" diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm index 7c52cea895e..269d2f76c6d 100644 --- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm @@ -5,7 +5,6 @@ /obj/machinery/atmospherics/unary/outlet_injector icon = 'icons/atmos/injector.dmi' icon_state = "map_injector" - layer = 3 name = "air injector" desc = "Passively injects air into its surroundings. Has a valve attached to it that can control flow rate." diff --git a/code/ATMOSPHERICS/mainspipe.dm b/code/ATMOSPHERICS/mainspipe.dm index 1b0c6175647..b03854418bf 100644 --- a/code/ATMOSPHERICS/mainspipe.dm +++ b/code/ATMOSPHERICS/mainspipe.dm @@ -34,7 +34,8 @@ obj/machinery/atmospherics/pipe/mains_component obj/machinery/atmospherics/mains_pipe icon = 'icons/obj/atmospherics/mainspipe.dmi' - layer = 2.4 //under wires with their 2.5 + layer = PIPES_LAYER + plane = PLATING_PLANE var/volume = 0 diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm index de81c602006..2d74a713c29 100644 --- a/code/ATMOSPHERICS/pipes/cap.dm +++ b/code/ATMOSPHERICS/pipes/cap.dm @@ -7,7 +7,6 @@ icon = 'icons/atmos/pipes.dmi' icon_state = "" level = 2 - layer = 2.4 //under wires with their 2.44 volume = 35 diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index 7370e10235e..7c964fb867b 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -44,37 +44,68 @@ What is the naming convention for planes or layers? #define PLANE_ADMIN2 -91 //And adminbuse #define PLANE_ADMIN3 -90 //And generating salt -#define SPACE_PLANE -32 // Reserved for use in space/parallax -#define PARALLAX_PLANE -30 // Reserved for use in space/parallax +#define SPACE_PLANE -82 // Reserved for use in space/parallax +#define PARALLAX_PLANE -80 // Reserved for use in space/parallax // OPENSPACE_PLANE reserves all planes between OPENSPACE_PLANE_START and OPENSPACE_PLANE_END inclusive -#define OPENSPACE_PLANE -55 // /turf/simulated/open will use OPENSPACE_PLANE + z (Valid z's being 2 thru 17) -#define OPENSPACE_PLANE_START -53 -#define OPENSPACE_PLANE_END -38 -#define OVER_OPENSPACE_PLANE -37 +#define OPENSPACE_PLANE -75 // /turf/simulated/open will use OPENSPACE_PLANE + z (Valid z's being 2 thru 17) +#define OPENSPACE_PLANE_START -73 +#define OPENSPACE_PLANE_END -58 +#define OVER_OPENSPACE_PLANE -57 + +// Turf Planes +#define SPACE_PLANE -43 // Space turfs themselves +#define PLATING_PLANE -44 // Plating + #define DISPOSAL_LAYER 2.1 // Under objects, even when planeswapped + #define WIRES_LAYER 2.2 // Under objects, even when planeswapped + #define PIPES_LAYER 2.3 // Under objects, even when planeswapped + #define ABOVE_UTILITY 2.5 // Above stuff like pipes and wires +#define TURF_PLANE -45 // Turfs themselves, most flooring + #define ABOVE_TURF_LAYER 2.1 // Snow and such +#define DECAL_PLANE -44 // Permanent decals +#define DIRTY_PLANE -43 // Nonpermanent decals +#define BLOOD_PLANE -42 // Blood is really dirty, but we can do special stuff if we separate it + +// Obj planes +#define OBJ_PLANE -35 + #define HIDING_LAYER 2.6 // Layer at which mobs hide to be under things like tables + #define DOOR_OPEN_LAYER 2.7 // Under all objects if opened. 2.7 due to tables being at 2.6 + #define UNDER_JUNK_LAYER 2.9 // Things that want to be slightly below common objects + // Turf/Obj layer boundary + #define ABOVE_JUNK_LAYER 3.1 // Things that want to be slightly above common objects + #define DOOR_CLOSED_LAYER 3.1 // Doors when closed + #define WINDOW_LAYER 3.2 // Windows + #define ON_WINDOW_LAYER 3.3 // Ontop of a window + #define SHOWER_OPEN_LAYER 3.4 // Showers when open + // Obj/Mob layer boundary + #define SHOWER_CLOSED_LAYER 4.2 // Should be converted to plane swaps + +// Mob planes +#define MOB_PLANE -25 + #define BELOW_MOB_LAYER 3.9 // Should be converted to plane swaps + #define ABOVE_MOB_LAYER 4.1 // Should be converted to plane swaps + +// Top plane (in the sense that it's the highest in 'the world' and not a UI element) +#define ABOVE_PLANE -10 //////////////////////////////////////////////////////////////////////////////////////// #define PLANE_WORLD 0 // BYOND's default value for plane, the "base plane" //////////////////////////////////////////////////////////////////////////////////////// + //#define AREA_LAYER 1 //For easy recordkeeping; this is a byond define + //#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define - #define DECALS_LAYER 2.01 - #define OVERTURF_LAYER 2.1 - #define HIDING_LAYER 2.45 //Layer at which mobs hide to be under things like tables - #define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6 + //#define OBJ_LAYER 3 //For easy recordkeeping; this is a byond define - #define DOOR_CLOSED_LAYER 3.1 //Above most items if closed - #define SHOWER_OPEN_LAYER 3.4 - #define BELOW_MOB_LAYER 3.9 + //#define MOB_LAYER 4 //For easy recordkeeping; this is a byond define - #define ABOVE_MOB_LAYER 4.1 - #define SHOWER_CLOSED_LAYER 4.2 - + //#define FLY_LAYER 5 //For easy recordkeeping; this is a byond define - #define LIGHTING_LAYER 11 //Layer that lighting used to be on (now it's on a plane) - #define HUD_LAYER 20 //Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots) - #define SCREEN_LAYER 22 //Mob HUD/effects layer + #define HUD_LAYER 20 // Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots) + #define SCREEN_LAYER 22 // Mob HUD/effects layer + +#define PLANE_PLANETLIGHTING 4 //Lighting on planets #define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives #define PLANE_LIGHTING_ABOVE 6 //For glowy eyes etc. that shouldn't be affected by darkness diff --git a/code/__defines/lighting.dm b/code/__defines/lighting.dm index 6b05896b8dd..00e473fc2a7 100644 --- a/code/__defines/lighting.dm +++ b/code/__defines/lighting.dm @@ -9,7 +9,6 @@ #define LIGHTING_LAMBERTIAN 0 // use lambertian shading for light sources #define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone -//#define LIGHTING_LAYER 10 // drawing layer for lighting overlays #define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects #define LIGHTING_ICON_STATE_DARK "soft_dark" // Change between "soft_dark" and "dark" to swap soft darkvision diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index bb17deacf49..18c8cb1ca71 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -9,7 +9,7 @@ #define CANPARALYSE 0x4 #define CANPUSH 0x8 #define LEAPING 0x10 -#define HIDING 0x20 +#define HIDING 0x20 #define PASSEMOTES 0x40 // Mob has a cortical borer or holders inside of it that need to see emotes. #define GODMODE 0x1000 #define FAKEDEATH 0x2000 // Replaces stuff like changeling.changeling_fakedeath. diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index 1f0df801414..2ec9da3b278 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -11,7 +11,7 @@ using.icon = 'icons/mob/screen1_alien.dmi' using.icon_state = (mymob.m_intent == "run" ? "running" : "walking") using.screen_loc = ui_acti - using.layer = 20 + using.layer = HUD_LAYER src.adding += using move_intent = using diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index f015976c32d..c63519c40f3 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -49,7 +49,6 @@ var/list/global_huds = list( /obj/screen/global_screen screen_loc = ui_entire_screen - layer = 17 plane = PLANE_FULLSCREEN mouse_opacity = 0 @@ -72,7 +71,6 @@ var/list/global_huds = list( darksight.icon = null darksight.screen_loc = "1,1" darksight.plane = PLANE_LIGHTING - darksight.plane = LIGHTING_LAYER + 0.1 //Marks the center of the screen, for things like ventcrawl centermarker = new /obj/screen() @@ -125,20 +123,17 @@ var/list/global_huds = list( for(i = 1, i <= 4, i++) O = vimpaired[i] O.icon_state = "dither50" - O.layer = 17 O.plane = PLANE_FULLSCREEN O.mouse_opacity = 0 O = darkMask[i] O.icon_state = "dither50" - O.layer = 17 O.plane = PLANE_FULLSCREEN O.mouse_opacity = 0 for(i = 5, i <= 8, i++) O = darkMask[i] O.icon_state = "black" - O.layer = 17 O.plane = PLANE_FULLSCREEN O.mouse_opacity = 2 diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index cab3e3bfca0..325a4a4b7ec 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -11,13 +11,13 @@ blobpwrdisplay.name = "blob power" blobpwrdisplay.icon_state = "block" blobpwrdisplay.screen_loc = ui_health - blobpwrdisplay.layer = 20 + blobpwrdisplay.layer = HUD_LAYER blobhealthdisplay = new /obj/screen() blobhealthdisplay.name = "blob health" blobhealthdisplay.icon_state = "block" blobhealthdisplay.screen_loc = ui_internal - blobhealthdisplay.layer = 20 + blobhealthdisplay.layer = HUD_LAYER mymob.client.screen = list() @@ -36,7 +36,7 @@ using.icon = ui_style using.icon_state = "intent_"+mymob.a_intent using.screen_loc = ui_zonesel - using.layer = 20 + using.layer = HUD_LAYER src.adding += using action_intent = using @@ -50,7 +50,7 @@ using.name = "help" using.icon = ico using.screen_loc = ui_zonesel - using.layer = 21 + using.layer = HUD_LAYER+0.01 src.adding += using help_intent = using @@ -61,7 +61,7 @@ using.name = "disarm" using.icon = ico using.screen_loc = ui_zonesel - using.layer = 21 + using.layer = HUD_LAYER+0.01 src.adding += using disarm_intent = using @@ -72,7 +72,7 @@ using.name = "grab" using.icon = ico using.screen_loc = ui_zonesel - using.layer = 21 + using.layer = HUD_LAYER+0.01 src.adding += using grab_intent = using @@ -83,7 +83,7 @@ using.name = I_HURT using.icon = ico using.screen_loc = ui_zonesel - using.layer = 21 + using.layer = HUD_LAYER+0.01 src.adding += using hurt_intent = using diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 8a6bb736f53..dc414df11f3 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -30,7 +30,7 @@ var/obj/screen/robot_inventory using.alpha = ui_alpha using.icon_state = "radio" using.screen_loc = ui_movi - using.layer = 20 + using.layer = HUD_LAYER src.adding += using //Module select @@ -43,7 +43,7 @@ var/obj/screen/robot_inventory using.alpha = ui_alpha using.icon_state = "inv1" using.screen_loc = ui_inv1 - using.layer = 20 + using.layer = HUD_LAYER src.adding += using mymob:inv1 = using @@ -55,7 +55,7 @@ var/obj/screen/robot_inventory using.alpha = ui_alpha using.icon_state = "inv2" using.screen_loc = ui_inv2 - using.layer = 20 + using.layer = HUD_LAYER src.adding += using mymob:inv2 = using @@ -67,7 +67,7 @@ var/obj/screen/robot_inventory using.alpha = ui_alpha using.icon_state = "inv3" using.screen_loc = ui_inv3 - using.layer = 20 + using.layer = HUD_LAYER src.adding += using mymob:inv3 = using @@ -81,7 +81,7 @@ var/obj/screen/robot_inventory using.alpha = ui_alpha using.icon_state = mymob.a_intent using.screen_loc = ui_acti - using.layer = 20 + using.layer = HUD_LAYER src.adding += using action_intent = using @@ -119,7 +119,7 @@ var/obj/screen/robot_inventory using.icon_state = "panel" using.alpha = ui_alpha using.screen_loc = ui_borg_panel - using.layer = 19 + using.layer = HUD_LAYER-0.01 src.adding += using //Store diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index f08727abf35..26c16804217 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -68,7 +68,7 @@ var/const/tk_maxrange = 15 flags = NOBLUDGEON //item_state = null w_class = ITEMSIZE_NO_CONTAINER - layer = 20 + layer = HUD_LAYER var/last_throw = 0 var/atom/movable/focus = null diff --git a/code/controllers/Processes/planet.dm b/code/controllers/Processes/planet.dm index f9fd57f7889..e39b5e81b8c 100644 --- a/code/controllers/Processes/planet.dm +++ b/code/controllers/Processes/planet.dm @@ -47,7 +47,8 @@ var/datum/controller/process/planet/planet_controller = null //Weather style needs redrawing if(P.needs_work & PLANET_PROCESS_WEATHER) P.needs_work &= ~PLANET_PROCESS_WEATHER - var/image/new_overlay = image(icon = P.weather_holder.current_weather.icon, icon_state = P.weather_holder.current_weather.icon_state, layer = LIGHTING_LAYER - 1) + var/image/new_overlay = image(icon = P.weather_holder.current_weather.icon, icon_state = P.weather_holder.current_weather.icon_state) + new_overlay.plane = PLANE_PLANETLIGHTING //Redraw weather icons for(var/T in P.planet_floors) var/turf/simulated/turf = T diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index 7fb3a56c61f..d7a91c9b4ff 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -234,7 +234,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle name = "star" var/speed = 10 var/direction = SOUTH - layer = 2 // TURF_LAYER + layer = TURF_LAYER + plane = TURF_PLANE /obj/effect/bgstar/New() ..() diff --git a/code/game/antagonist/antagonist_update.dm b/code/game/antagonist/antagonist_update.dm index 7cf17b5640a..16c27f82c7e 100644 --- a/code/game/antagonist/antagonist_update.dm +++ b/code/game/antagonist/antagonist_update.dm @@ -33,7 +33,9 @@ if(!antag_indicator || !other.current || !recipient.current) return var/indicator = (faction_indicator && (other in faction_members)) ? faction_indicator : antag_indicator - return image('icons/mob/mob.dmi', loc = other.current, icon_state = indicator, layer = LIGHTING_LAYER+0.1) + var/image/returnimage = image('icons/mob/mob.dmi', loc = other.current, icon_state = indicator) + returnimage.plane = PLANE_LIGHTING_ABOVE + return returnimage /datum/antagonist/proc/update_all_icons() if(!antag_indicator) diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index c79e6abf17a..df3d06c1412 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -13,82 +13,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station */ - - -/area - var/fire = null - var/atmos = 1 - var/atmosalm = 0 - var/poweralm = 1 - var/party = null - level = null - name = "Unknown" - icon = 'icons/turf/areas.dmi' - icon_state = "unknown" - layer = 10 - luminosity = 0 - mouse_opacity = 0 - var/lightswitch = 1 - - var/eject = null - - var/debug = 0 - var/requires_power = 1 - var/always_unpowered = 0 //this gets overriden to 1 for space in area/New() - - var/power_equip = 1 - var/power_light = 1 - var/power_environ = 1 - var/music = null - var/used_equip = 0 - var/used_light = 0 - var/used_environ = 0 - - var/has_gravity = 1 - var/obj/machinery/power/apc/apc = null - var/no_air = null -// var/list/lights // list of all lights on this area - var/list/all_doors = null //Added by Strumpetplaya - Alarm Change - Contains a list of doors adjacent to this area - var/firedoors_closed = 0 - var/list/ambience = list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg','sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg','sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg','sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg','sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg','sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg') - var/list/forced_ambience = null - var/sound_env = STANDARD_STATION - var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf - -/*Adding a wizard area teleport list because motherfucking lag -- Urist*/ -/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ -var/list/teleportlocs = list() - -/hook/startup/proc/setupTeleportLocs() - for(var/area/AR in world) - if(istype(AR, /area/shuttle) || istype(AR, /area/syndicate_station) || istype(AR, /area/wizard_station)) continue - if(teleportlocs.Find(AR.name)) continue - var/turf/picked = pick(get_area_turfs(AR.type)) - if (picked.z in using_map.station_levels) - teleportlocs += AR.name - teleportlocs[AR.name] = AR - - teleportlocs = sortAssoc(teleportlocs) - - return 1 - -var/list/ghostteleportlocs = list() - -/hook/startup/proc/setupGhostTeleportLocs() - for(var/area/AR in world) - if(ghostteleportlocs.Find(AR.name)) continue - if(istype(AR, /area/aisat) || istype(AR, /area/derelict) || istype(AR, /area/tdome) || istype(AR, /area/shuttle/specops/centcom)) - ghostteleportlocs += AR.name - ghostteleportlocs[AR.name] = AR - var/turf/picked = pick(get_area_turfs(AR.type)) - if (picked.z in using_map.player_levels) - ghostteleportlocs += AR.name - ghostteleportlocs[AR.name] = AR - - ghostteleportlocs = sortAssoc(ghostteleportlocs) - - return 1 - /*-----------------------------------------------------------------------------*/ ///////// diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index a5c2fc2f440..c7a653a4c34 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -1,15 +1,49 @@ // Areas.dm - - -// === /area + var/fire = null + var/atmos = 1 + var/atmosalm = 0 + var/poweralm = 1 + var/party = null + level = null + name = "Unknown" + icon = 'icons/turf/areas.dmi' + icon_state = "unknown" + plane = PLANE_LIGHTING_ABOVE //In case we color them + luminosity = 0 + mouse_opacity = 0 + var/lightswitch = 1 + + var/eject = null + + var/debug = 0 + var/requires_power = 1 + var/always_unpowered = 0 //this gets overriden to 1 for space in area/New() + + var/power_equip = 1 + var/power_light = 1 + var/power_environ = 1 + var/music = null + var/used_equip = 0 + var/used_light = 0 + var/used_environ = 0 + + var/has_gravity = 1 + var/obj/machinery/power/apc/apc = null + var/no_air = null +// var/list/lights // list of all lights on this area + var/list/all_doors = null //Added by Strumpetplaya - Alarm Change - Contains a list of doors adjacent to this area + var/firedoors_closed = 0 + var/list/ambience = list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg','sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg','sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg','sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg','sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg','sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg') + var/list/forced_ambience = null + var/sound_env = STANDARD_STATION + var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf var/global/global_uid = 0 var/uid /area/New() icon_state = "" - layer = 10 uid = ++global_uid all_areas += src @@ -333,3 +367,37 @@ var/list/mob/living/forced_ambiance_list = new /area/drop_location() CRASH("Bad op: area/drop_location() called") + +/*Adding a wizard area teleport list because motherfucking lag -- Urist*/ +/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ +var/list/teleportlocs = list() + +/hook/startup/proc/setupTeleportLocs() + for(var/area/AR in world) + if(istype(AR, /area/shuttle) || istype(AR, /area/syndicate_station) || istype(AR, /area/wizard_station)) continue + if(teleportlocs.Find(AR.name)) continue + var/turf/picked = pick(get_area_turfs(AR.type)) + if (picked.z in using_map.station_levels) + teleportlocs += AR.name + teleportlocs[AR.name] = AR + + teleportlocs = sortAssoc(teleportlocs) + + return 1 + +var/list/ghostteleportlocs = list() + +/hook/startup/proc/setupGhostTeleportLocs() + for(var/area/AR in world) + if(ghostteleportlocs.Find(AR.name)) continue + if(istype(AR, /area/aisat) || istype(AR, /area/derelict) || istype(AR, /area/tdome) || istype(AR, /area/shuttle/specops/centcom)) + ghostteleportlocs += AR.name + ghostteleportlocs[AR.name] = AR + var/turf/picked = pick(get_area_turfs(AR.type)) + if (picked.z in using_map.player_levels) + ghostteleportlocs += AR.name + ghostteleportlocs[AR.name] = AR + + ghostteleportlocs = sortAssoc(ghostteleportlocs) + + return 1 diff --git a/code/game/atoms.dm b/code/game/atoms.dm index e18970802e4..dda3e0a6b57 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1,5 +1,5 @@ /atom - layer = 2 + layer = TURF_LAYER //This was here when I got here. Why though? var/level = 2 var/flags = 0 var/list/fingerprints diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 0cd09b8a576..5311d642a27 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1,5 +1,5 @@ /atom/movable - layer = 3 + layer = OBJ_LAYER appearance_flags = TILE_BOUND|PIXEL_SCALE var/last_move = null var/anchored = 0 diff --git a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm index fb4888ee205..2c47b8e1624 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm @@ -10,7 +10,7 @@ announce=0 cause_hell=0 - layer=LIGHTING_LAYER+2 // ITS SO BRIGHT + plane = PLANE_LIGHTING_ABOVE // ITS SO BRIGHT consume_range = 6 @@ -79,7 +79,8 @@ var/turf/T_mob = get_turf(src) if((R.z == T_mob.z) && (get_dist(R,T_mob) <= (R.consume_range+10)) && !(R in view(T_mob))) if(!riftimage) - riftimage = image('icons/obj/rift.dmi',T_mob,"rift",LIGHTING_LAYER+2,1) + riftimage = image('icons/obj/rift.dmi',T_mob,"rift",1,1) + riftimage.plane = PLANE_LIGHTING_ABOVE riftimage.mouse_opacity = 0 var/new_x = 32 * (R.x - T_mob.x) + R.pixel_x diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index c59c67c3001..b34d1565a03 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -4,7 +4,7 @@ name = "Bluespace Gigabeacon" desc = "A device that draws power from bluespace and creates a permanent tracking beacon." level = 1 // underfloor - layer = 2.5 + layer = UNDER_JUNK_LAYER anchored = 1 use_power = 1 idle_power_usage = 0 diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm index 0ea5527df21..dd79d5acc19 100644 --- a/code/game/machinery/ai_slipper.dm +++ b/code/game/machinery/ai_slipper.dm @@ -2,7 +2,6 @@ name = "\improper AI Liquid Dispenser" icon = 'icons/obj/device.dmi' icon_state = "motion0" - layer = 3 anchored = 1.0 use_power = 1 idle_power_usage = 10 diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 769dd9c39fb..70d8864e2dc 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -6,7 +6,8 @@ use_power = 2 idle_power_usage = 5 active_power_usage = 10 - layer = 5 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER var/list/network = list(NETWORK_DEFAULT) var/c_tag = null diff --git a/code/game/machinery/computer3/lapvend.dm b/code/game/machinery/computer3/lapvend.dm index e1e70ca3a7c..cbfa8686bce 100644 --- a/code/game/machinery/computer3/lapvend.dm +++ b/code/game/machinery/computer3/lapvend.dm @@ -3,7 +3,6 @@ desc = "A generic vending machine." icon = 'icons/obj/vending.dmi' icon_state = "robotics" - layer = 2.9 anchored = 1 density = 1 var/obj/machinery/computer3/laptop/vended/newlap = null diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 6709cb23635..f7ab7e7a7ec 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -6,13 +6,15 @@ icon_state = "pod_preview" density = 1 anchored = 1.0 - layer = 2.8 + layer = UNDER_JUNK_LAYER interact_offline = 1 var/on = 0 use_power = 1 idle_power_usage = 20 active_power_usage = 200 + buckle_lying = FALSE + buckle_dir = SOUTH var/temperature_archived var/mob/living/carbon/occupant = null @@ -20,12 +22,29 @@ var/current_heat_capacity = 50 + var/image/fluid + /obj/machinery/atmospherics/unary/cryo_cell/New() ..() icon = 'icons/obj/cryogenics_split.dmi' - update_icon() + icon_state = "base" initialize_directions = dir +/obj/machinery/atmospherics/unary/cryo_cell/initialize() + . = ..() + var/image/tank = image(icon,"tank") + tank.alpha = 200 + tank.pixel_y = 18 + tank.plane = MOB_PLANE + tank.layer = MOB_LAYER+0.2 //Above fluid + fluid = image(icon, "tube_filler") + fluid.pixel_y = 18 + fluid.alpha = 200 + fluid.plane = MOB_PLANE + fluid.layer = MOB_LAYER+0.1 //Below glass, above mob + add_overlay(tank) + update_icon() + /obj/machinery/atmospherics/unary/cryo_cell/Destroy() var/turf/T = src.loc T.contents += contents @@ -153,6 +172,7 @@ if(beaker) beaker.loc = get_step(src.loc, SOUTH) beaker = null + update_icon() if(href_list["ejectOccupant"]) if(!occupant || isslime(usr) || ispAI(usr)) @@ -172,6 +192,7 @@ user.drop_item() G.loc = src user.visible_message("[user] adds \a [G] to \the [src]!", "You add \a [G] to \the [src]!") + update_icon() else if(istype(G, /obj/item/weapon/grab)) var/obj/item/weapon/grab/grab = G if(!ismob(grab.affecting)) @@ -191,40 +212,23 @@ put_mob(target) /obj/machinery/atmospherics/unary/cryo_cell/update_icon() - overlays.Cut() - icon_state = "pod[on]" - var/image/I - - I = image(icon, "pod[on]_top") - I.layer = 5 // this needs to be fairly high so it displays over most things, but it needs to be under lighting (at 10) - I.pixel_z = 32 - overlays += I - - if(occupant) - var/image/pickle = image(occupant.icon, occupant.icon_state) - pickle.overlays = occupant.overlays - pickle.pixel_z = 18 - pickle.layer = 5 - overlays += pickle - - I = image(icon, "lid[on]") - I.layer = 5 - overlays += I - - I = image(icon, "lid[on]_top") - I.layer = 5 - I.pixel_z = 32 - overlays += I + cut_overlay(fluid) + fluid.color = null + if(on) + if(beaker) + fluid.color = beaker.reagents.get_color() + add_overlay(fluid) /obj/machinery/atmospherics/unary/cryo_cell/proc/process_occupant() if(air_contents.total_moles < 10) return if(occupant) - if(occupant.stat == 2) + if(occupant.stat >= DEAD) return occupant.bodytemperature += 2*(air_contents.temperature - occupant.bodytemperature)*current_heat_capacity/(current_heat_capacity + air_contents.heat_capacity()) occupant.bodytemperature = max(occupant.bodytemperature, air_contents.temperature) // this is so ugly i'm sorry for doing it i'll fix it later i promise - occupant.stat = 1 + occupant.stat = UNCONSCIOUS + occupant.dir = SOUTH if(occupant.bodytemperature < T0C) occupant.sleeping = max(5, (1/occupant.bodytemperature)*2000) occupant.Paralyse(max(5, (1/occupant.bodytemperature)*3000)) @@ -273,14 +277,16 @@ if(occupant.client) occupant.client.eye = occupant.client.mob occupant.client.perspective = MOB_PERSPECTIVE + vis_contents -= occupant + occupant.pixel_x = occupant.default_pixel_x + occupant.pixel_y = occupant.default_pixel_y occupant.loc = get_step(src.loc, SOUTH) //this doesn't account for walls or anything, but i don't forsee that being a problem. if(occupant.bodytemperature < 261 && occupant.bodytemperature >= 70) //Patch by Aranclanos to stop people from taking burn damage after being ejected occupant.bodytemperature = 261 // Changed to 70 from 140 by Zuhayr due to reoccurance of bug. -// occupant.metabslow = 0 + unbuckle_mob(occupant, force = TRUE) occupant = null current_heat_capacity = initial(current_heat_capacity) update_use_power(1) - update_icon() return /obj/machinery/atmospherics/unary/cryo_cell/proc/put_mob(mob/living/carbon/M as mob) if(stat & (NOPOWER|BROKEN)) @@ -307,6 +313,9 @@ if(M.health > -100 && (M.health < 0 || M.sleeping)) M << "You feel a cold liquid surround you. Your skin starts to freeze up." occupant = M + buckle_mob(occupant, forced = TRUE, check_loc = FALSE) + vis_contents |= occupant + occupant.pixel_y += 19 current_heat_capacity = HEAT_CAPACITY_HUMAN update_use_power(2) // M.metabslow = 1 diff --git a/code/game/machinery/holosign.dm b/code/game/machinery/holosign.dm index 215238a80b9..39a91b8aff4 100644 --- a/code/game/machinery/holosign.dm +++ b/code/game/machinery/holosign.dm @@ -4,7 +4,7 @@ desc = "Small wall-mounted holographic projector" icon = 'icons/obj/holosign.dmi' icon_state = "sign_off" - layer = 4 + plane = MOB_PLANE use_power = 1 idle_power_usage = 2 active_power_usage = 4 diff --git a/code/game/machinery/kitchen/icecream.dm b/code/game/machinery/kitchen/icecream.dm index fab6319e260..09cb3289ed1 100644 --- a/code/game/machinery/kitchen/icecream.dm +++ b/code/game/machinery/kitchen/icecream.dm @@ -172,7 +172,6 @@ name = "ice cream cone" desc = "Delicious waffle cone, but no ice cream." icon_state = "icecream_cone_waffle" //default for admin-spawned cones, href_list["cone"] should overwrite this all the time - layer = 3.1 bitesize = 3 var/ice_creamed = 0 diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index fa81ff16203..3da253e6827 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -2,7 +2,6 @@ name = "microwave" icon = 'icons/obj/kitchen.dmi' icon_state = "mw" - layer = 2.9 density = 1 anchored = 1 use_power = 1 diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index a2f5c00ad12..b2c3d21b689 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -4,7 +4,6 @@ name = "\improper SmartFridge" icon = 'icons/obj/vending.dmi' icon_state = "smartfridge" - layer = 2.9 density = 1 anchored = 1 use_power = 1 diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 673e3663132..874f8876b97 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -97,6 +97,7 @@ Class Procs: name = "machinery" icon = 'icons/obj/stationobjs.dmi' w_class = ITEMSIZE_NO_CONTAINER + layer = UNDER_JUNK_LAYER var/stat = 0 var/emagged = 0 diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index af61e934246..8022235736a 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -9,8 +9,7 @@ icon_state = "floor_magnet-f" name = "Electromagnetic Generator" desc = "A device that uses station power to create points of magnetic energy." - level = 1 // underfloor - layer = 2.5 + plane = PLATING_PLANE anchored = 1 use_power = 1 idle_power_usage = 50 diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index ac0af163786..7e472c8ecab 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -8,8 +8,7 @@ var/global/list/navbeacons = list() // no I don't like putting this in, but it w icon_state = "navbeacon0-f" name = "navigation beacon" desc = "A beacon used for bot navigation." - level = 1 // underfloor - layer = 2.5 + plane = PLATING_PLANE anchored = 1 var/open = 0 // true if cover is open var/locked = 1 // true if controls are locked diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm index 48bd028c09f..0ec65cc30db 100644 --- a/code/game/machinery/overview.dm +++ b/code/game/machinery/overview.dm @@ -168,7 +168,7 @@ qdel(I) qdel(J) H.icon = HI - H.layer = 25 + H.hud_layerise() usr.mapobjs += H #else @@ -287,7 +287,7 @@ H.icon = I qdel(I) - H.layer = 25 + H.hud_layerise() usr.mapobjs += H #endif diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 4b452295940..939b4da1d04 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -6,7 +6,6 @@ desc = "A generic vending machine." icon = 'icons/obj/vending.dmi' icon_state = "generic" - layer = 2.9 anchored = 1 density = 1 diff --git a/code/game/mecha/combat/gorilla.dm b/code/game/mecha/combat/gorilla.dm index b6f19156672..cc5dacebc37 100644 --- a/code/game/mecha/combat/gorilla.dm +++ b/code/game/mecha/combat/gorilla.dm @@ -51,7 +51,7 @@ desc = "... Blitzkrieg?" icon = 'icons/mecha/mecha64x64.dmi' icon_state = "pzrwreck" - layer = 4 // so it overlaps other people + plane = MOB_PLANE pixel_x = -16 anchored = 1 // It's fucking huge. You aren't moving it. diff --git a/code/game/mecha/mech_sensor.dm b/code/game/mecha/mech_sensor.dm index 87a9863ee8c..5173f182cea 100644 --- a/code/game/mecha/mech_sensor.dm +++ b/code/game/mecha/mech_sensor.dm @@ -7,7 +7,7 @@ density = 1 throwpass = 1 use_power = 1 - layer = 3.3 + layer = ON_WINDOW_LAYER power_channel = EQUIP var/on = 0 var/id_tag = null diff --git a/code/game/objects/effects/alien/aliens.dm b/code/game/objects/effects/alien/aliens.dm index 2c864f0a56c..7a79c21e1ef 100644 --- a/code/game/objects/effects/alien/aliens.dm +++ b/code/game/objects/effects/alien/aliens.dm @@ -147,7 +147,8 @@ anchored = 1 density = 0 - layer = 2 + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER var/health = 15 var/obj/effect/alien/weeds/node/linked_node = null @@ -155,7 +156,7 @@ icon_state = "weednode" name = "purple sac" desc = "Weird purple octopus-like thing." - layer = 3 + layer = ABOVE_TURF_LAYER+0.01 light_range = NODERANGE var/node_range = NODERANGE diff --git a/code/game/objects/effects/chem/chemsmoke.dm b/code/game/objects/effects/chem/chemsmoke.dm index be7e759a636..436ebabcc92 100644 --- a/code/game/objects/effects/chem/chemsmoke.dm +++ b/code/game/objects/effects/chem/chemsmoke.dm @@ -161,7 +161,7 @@ if(chemholder.reagents.reagent_list.len) chemholder.reagents.trans_to_obj(smoke, chemholder.reagents.total_volume / dist, copy = 1) //copy reagents to the smoke so mob/breathe() can handle inhaling the reagents smoke.icon = I - smoke.layer = 6 + smoke.plane = ABOVE_PLANE smoke.set_dir(pick(cardinal)) smoke.pixel_x = -32 + rand(-8, 8) smoke.pixel_y = -32 + rand(-8, 8) diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm index c04540535bc..b69226815e2 100644 --- a/code/game/objects/effects/decals/Cleanable/fuel.dm +++ b/code/game/objects/effects/decals/Cleanable/fuel.dm @@ -2,7 +2,7 @@ //Liquid fuel is used for things that used to rely on volatile fuels or phoron being contained to a couple tiles. icon = 'icons/effects/effects.dmi' icon_state = "fuel" - layer = TURF_LAYER+0.2 + plane = DIRTY_PLANE anchored = 1 var/amount = 1 diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 46b9d3645c8..90f708ff9df 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -10,7 +10,7 @@ var/global/list/image/splatter_cache=list() gender = PLURAL density = 0 anchored = 1 - layer = 2 + plane = BLOOD_PLANE icon = 'icons/effects/blood.dmi' icon_state = "mfloor1" random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7") @@ -179,7 +179,6 @@ var/global/list/image/splatter_cache=list() gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/blood.dmi' icon_state = "gibbl5" random_icon_states = list("gib1", "gib2", "gib3", "gib5", "gib6") @@ -236,7 +235,6 @@ var/global/list/image/splatter_cache=list() gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/blood.dmi' icon_state = "mucus" random_icon_states = list("mucus") diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index ab01bfa0050..1ef83bc7223 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -4,7 +4,6 @@ gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/obj/objects.dmi' icon_state = "shards" @@ -36,7 +35,6 @@ gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/effects.dmi' icon_state = "dirt" mouse_opacity = 0 @@ -47,7 +45,6 @@ gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/effects.dmi' icon_state = "flour" @@ -57,7 +54,6 @@ gender = PLURAL density = 0 anchored = 1 - layer = 2 light_range = 1 icon = 'icons/effects/effects.dmi' icon_state = "greenglow" @@ -67,7 +63,7 @@ desc = "Somebody should remove that." density = 0 anchored = 1 - layer = 3 + plane = OBJ_PLANE icon = 'icons/effects/effects.dmi' icon_state = "cobweb1" @@ -76,7 +72,7 @@ desc = "It looks like a melted... something." density = 0 anchored = 1 - layer = 3 + plane = OBJ_PLANE icon = 'icons/obj/chemical.dmi' icon_state = "molten" @@ -85,7 +81,7 @@ desc = "Somebody should remove that." density = 0 anchored = 1 - layer = 3 + plane = OBJ_PLANE icon = 'icons/effects/effects.dmi' icon_state = "cobweb2" @@ -96,7 +92,6 @@ gender = PLURAL density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/blood.dmi' icon_state = "vomit_1" random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4") @@ -107,7 +102,6 @@ desc = "It's red." density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3") @@ -116,7 +110,6 @@ desc = "Seems like this one won't hatch." density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3") @@ -125,7 +118,6 @@ desc = "It's pie cream from a cream pie." density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("smashed_pie") @@ -134,7 +126,6 @@ desc = "Some kind of fruit smear." density = 0 anchored = 1 - layer = 2 icon = 'icons/effects/blood.dmi' icon_state = "mfloor1" random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7") diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 2db1e5e9486..f7965e092d0 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -1,4 +1,5 @@ /obj/effect/decal/cleanable + plane = DIRTY_PLANE var/list/random_icon_states = list() /obj/effect/decal/cleanable/clean_blood(var/ignore = 0) diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index 20047ced124..55bb54b8036 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -2,7 +2,7 @@ name = "rune" desc = "A rune drawn in crayon." icon = 'icons/obj/rune.dmi' - layer = 2.1 + plane = DIRTY_PLANE anchored = 1 New(location,main = "#FFFFFF",shade = "#000000",var/type = "rune") diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index 964a1301b89..f3a75ce3c28 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -3,7 +3,7 @@ desc = "It's an arrow hanging in mid-air. There may be a wizard about." icon = 'icons/mob/screen1.dmi' icon_state = "arrow" - layer = 16.0 + plane = ABOVE_PLANE anchored = 1 mouse_opacity = 0 @@ -11,4 +11,4 @@ /obj/effect/decal/spraystill density = 0 anchored = 1 - layer = 50 \ No newline at end of file + plane = ABOVE_PLANE \ No newline at end of file diff --git a/code/game/objects/effects/decals/warning_stripes.dm b/code/game/objects/effects/decals/warning_stripes.dm index e22acfad74e..db7c4bf74f1 100644 --- a/code/game/objects/effects/decals/warning_stripes.dm +++ b/code/game/objects/effects/decals/warning_stripes.dm @@ -1,6 +1,5 @@ /obj/effect/decal/warning_stripes icon = 'icons/effects/warning_stripes.dmi' - layer = 2 /obj/effect/decal/warning_stripes/New() . = ..() diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index 349400226a1..aaebab43550 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -26,7 +26,8 @@ desc = "Something swinging really wide." icon = 'icons/effects/96x96.dmi' icon_state = "cleave" - layer = 6 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER time_to_die = 6 alpha = 140 mouse_opacity = 0 diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index d6dea13c511..9f4f0fa1185 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -17,7 +17,8 @@ icon = 'icons/misc/beach2.dmi' icon_state = "palm1" density = 1 - layer = 5 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER anchored = 1 /obj/effect/overlay/palmtree_l @@ -25,7 +26,8 @@ icon = 'icons/misc/beach2.dmi' icon_state = "palm2" density = 1 - layer = 5 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER anchored = 1 /obj/effect/overlay/coconut @@ -37,7 +39,7 @@ name = "Bluespace" icon = 'icons/turf/space.dmi' icon_state = "bluespacify" - layer = 10 + plane = ABOVE_PLANE /obj/effect/overlay/wallrot name = "wallrot" @@ -45,7 +47,8 @@ icon = 'icons/effects/wallrot.dmi' anchored = 1 density = 1 - layer = 5 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER mouse_opacity = 0 /obj/effect/overlay/wallrot/New() @@ -70,7 +73,8 @@ /obj/effect/overlay/snow/floor icon_state = "snowfloor" - layer = 2.01 //Just above floor + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER mouse_opacity = 0 //Don't block underlying tile interactions /obj/effect/overlay/snow/floor/edges @@ -81,11 +85,12 @@ /obj/effect/overlay/snow/airlock icon_state = "snowairlock" - layer = 3.2 //Just above airlocks + layer = DOOR_CLOSED_LAYER+0.01 /obj/effect/overlay/snow/floor/pointy icon_state = "snowfloorpointy" /obj/effect/overlay/snow/wall icon_state = "snowwall" - layer = 5 //Same as lights so humans can stand under it + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index a26c1169d5f..d3b9853e063 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -123,7 +123,7 @@ desc = "It never stays still for long." icon_state = "spiderling" anchored = 0 - layer = 2.7 + layer = HIDING_LAYER health = 3 var/last_itch = 0 var/amount_grown = -1 diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index f1c9aa2d145..e24a727b99b 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -104,7 +104,6 @@ bmark.pixel_x = p_x bmark.pixel_y = p_y bmark.icon = 'icons/effects/effects.dmi' - bmark.layer = 3.5 bmark.icon_state = "scorch" if(decaltype == 1) diff --git a/code/game/objects/items/weapons/id cards/cards.dm b/code/game/objects/items/weapons/id cards/cards.dm index b5654dade7a..d0b2534463c 100644 --- a/code/game/objects/items/weapons/id cards/cards.dm +++ b/code/game/objects/items/weapons/id cards/cards.dm @@ -46,7 +46,6 @@ name = "\proper the coordinates to clown planet" icon_state = "data" item_state = "card-id" - layer = 3 level = 2 desc = "This card contains coordinates to the fabled Clown Planet. Handle with care." function = "teleporter" diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index 3bb0c89bdc4..43183d45f44 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -30,7 +30,7 @@ var/list/tape_roll_applications = list() name = "tape" icon = 'icons/policetape.dmi' anchored = 1 - layer = 3.2 + layer = WINDOW_LAYER var/lifted = 0 var/crumpled = 0 var/tape_dir = 0 @@ -257,7 +257,7 @@ var/list/tape_roll_applications = list() else var/obj/item/tape/P = new tape_type(T) P.update_icon() - P.layer = 3.2 + P.layer = WINDOW_LAYER user << "You finish placing \the [src]." if (istype(A, /turf/simulated/floor) ||istype(A, /turf/unsimulated/floor)) @@ -307,10 +307,11 @@ var/list/tape_roll_applications = list() /obj/item/tape/proc/lift(time) lifted = 1 - layer = 8 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER spawn(time) lifted = 0 - layer = initial(layer) + reset_plane_and_layer() // Returns a list of all tape objects connected to src, including itself. /obj/item/tape/proc/gettapeline() diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index 30257a2b84b..83e944f5934 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -131,7 +131,7 @@ icon = 'icons/obj/bureaucracy.dmi' icon_state = "tape" w_class = ITEMSIZE_TINY - layer = 4 + plane = MOB_PLANE anchored = 1 //it's sticky, no you cant move it var/obj/item/weapon/stuck = null diff --git a/code/game/objects/items/weapons/trays.dm b/code/game/objects/items/weapons/trays.dm index 68a2c3a774c..8d9977cc17f 100644 --- a/code/game/objects/items/weapons/trays.dm +++ b/code/game/objects/items/weapons/trays.dm @@ -188,7 +188,7 @@ carrying.Add(I) Img.icon = I.icon Img.icon_state = I.icon_state - Img.layer = 30 + I.layer + Img.layer = layer + I.layer*0.01 if(istype(I, /obj/item/weapon/material)) var/obj/item/weapon/material/O = I if(O.applies_material_colour) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 31d5189ddbe..3835b2a24bb 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -1,4 +1,6 @@ /obj + layer = OBJ_LAYER + plane = OBJ_PLANE //Used to store information about the contents of the object. var/list/matter var/w_class // Size of the object. diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 5c3542015c5..9b3d866d2bf 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -10,7 +10,8 @@ LINEN BINS icon = 'icons/obj/items.dmi' icon_state = "sheet" slot_flags = SLOT_BACK - layer = 4.0 + plane = MOB_PLANE + layer = BELOW_MOB_LAYER throwforce = 1 throw_speed = 1 throw_range = 2 @@ -19,9 +20,9 @@ LINEN BINS /obj/item/weapon/bedsheet/attack_self(mob/user as mob) user.drop_item() if(layer == initial(layer)) - layer = MOB_LAYER + 0.1 + layer = ABOVE_MOB_LAYER else - layer = initial(layer) + reset_plane_and_layer() add_fingerprint(user) return diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index a3ff9ac9afd..a22bbae0d25 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -2,7 +2,7 @@ icon_state = "girder" anchored = 1 density = 1 - layer = 2 + plane = PLATING_PLANE w_class = ITEMSIZE_HUGE var/state = 0 var/health = 200 diff --git a/code/game/objects/structures/gravemarker.dm b/code/game/objects/structures/gravemarker.dm index a10cd0bf6ea..e20591b9399 100644 --- a/code/game/objects/structures/gravemarker.dm +++ b/code/game/objects/structures/gravemarker.dm @@ -8,7 +8,7 @@ throwpass = 1 climbable = 1 - layer = 3.1 //Above dirt piles + layer = ABOVE_JUNK_LAYER //Maybe make these calculate based on material? var/health = 100 diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 6fea7e6ecee..ee809999163 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -7,7 +7,7 @@ anchored = 1 flags = CONDUCT pressure_resistance = 5*ONE_ATMOSPHERE - layer = 2.9 + layer = UNDER_JUNK_LAYER explosion_resistance = 1 var/health = 10 var/destroyed = 0 diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index c042b8fc9a6..d9ec122c555 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -6,7 +6,7 @@ density = 0 anchored = 1.0 w_class = ITEMSIZE_NORMAL - layer = 2.3 //under pipes + plane = PLATING_PLANE // flags = CONDUCT /obj/structure/lattice/initialize() diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 732bb1b55de..d0324c98bf1 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -148,7 +148,7 @@ icon = 'icons/obj/stationobjs.dmi' icon_state = "morguet" density = 1 - layer = 2.0 + plane = TURF_PLANE var/obj/structure/morgue/connected = null anchored = 1 throwpass = 1 diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm index 27bb902aea8..e67750b8f30 100644 --- a/code/game/objects/structures/railing.dm +++ b/code/game/objects/structures/railing.dm @@ -6,7 +6,7 @@ density = 1 throwpass = 1 climbable = 1 - layer = 3.2 //Just above doors + layer = WINDOW_LAYER anchored = 1 flags = ON_BORDER icon_state = "railing0" diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 7f78e8f0e71..37edb603c1d 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -172,7 +172,8 @@ obj/structure/safe/ex_act(severity) icon_state = "floorsafe" density = 0 level = 1 //underfloor - layer = 2.5 + plane = TURF_PLANE + layer = ABOVE_UTILITY /obj/structure/safe/floor/initialize() . = ..() diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index 1d68de0d25d..33c6d6501cb 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -3,7 +3,7 @@ anchored = 1 opacity = 0 density = 0 - layer = 3.5 + layer = ABOVE_JUNK_LAYER w_class = ITEMSIZE_NORMAL /obj/structure/sign/ex_act(severity) diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index ed9c4e0301a..390e3c84b9c 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -47,15 +47,17 @@ if(isnull(stool_cache[cache_key])) var/image/I = image(icon, "[base_icon]_armrest") I.layer = MOB_LAYER + 0.1 + I.plane = MOB_PLANE I.color = padding_material.icon_colour stool_cache[cache_key] = I overlays |= stool_cache[cache_key] /obj/structure/bed/chair/proc/update_layer() if(src.dir == NORTH) - src.layer = FLY_LAYER + plane = MOB_PLANE + layer = MOB_LAYER + 0.1 else - src.layer = OBJ_LAYER + reset_plane_and_layer() /obj/structure/bed/chair/set_dir() ..() diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index 83396b363e9..646e52218c1 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -29,7 +29,7 @@ W.density = 1 user.remove_from_mob(W) W.loc = loc - W.layer = 3.1 + W.layer = ABOVE_JUNK_LAYER pinned_target = W user << "You slide the target into the stake." return diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm index 0f9b4a603a8..c260103a567 100644 --- a/code/game/objects/structures/transit_tubes.dm +++ b/code/game/objects/structures/transit_tubes.dm @@ -7,7 +7,7 @@ icon = 'icons/obj/pipes/transit_tube.dmi' icon_state = "E-W" density = 1 - layer = 3.1 + layer = ABOVE_JUNK_LAYER anchored = 1.0 var/list/tube_dirs = null var/exit_delay = 2 diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index eab6f203fc4..36da7485adb 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -5,7 +5,7 @@ density = 1 w_class = ITEMSIZE_NORMAL - layer = 3.2//Just above doors + layer = WINDOW_LAYER pressure_resistance = 4*ONE_ATMOSPHERE anchored = 1.0 flags = ON_BORDER @@ -462,7 +462,7 @@ if(ratio > 75) return - var/image/I = image(icon, "damage[ratio]", layer + 0.1) + var/image/I = image(icon, "damage[ratio]", layer = layer + 0.1) overlays += I return diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index 3b657e57f2b..3cc0bb8ab9e 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -46,7 +46,8 @@ var/list/mechtoys = list( icon_state = "plasticflaps" density = 0 anchored = 1 - layer = 4 + layer = MOB_LAYER + plane = MOB_PLANE explosion_resistance = 5 var/list/mobs_can_pass = list( /mob/living/bot, diff --git a/code/game/turfs/flooring/flooring_decals.dm b/code/game/turfs/flooring/flooring_decals.dm index c41e316badc..957cc20389e 100644 --- a/code/game/turfs/flooring/flooring_decals.dm +++ b/code/game/turfs/flooring/flooring_decals.dm @@ -6,7 +6,7 @@ var/list/floor_decals = list() /obj/effect/floor_decal name = "floor decal" icon = 'icons/turf/flooring/decals.dmi' - layer = DECALS_LAYER + plane = DECAL_PLANE var/supplied_dir /obj/effect/floor_decal/New(var/newloc, var/newdir, var/newcolour) diff --git a/code/game/turfs/simulated/floor_icon.dm b/code/game/turfs/simulated/floor_icon.dm index c28aedddcab..e1b49762ecd 100644 --- a/code/game/turfs/simulated/floor_icon.dm +++ b/code/game/turfs/simulated/floor_icon.dm @@ -7,7 +7,7 @@ var/image/no_ceiling_image = null return TRUE /proc/cache_no_ceiling_image() - no_ceiling_image = image(icon = 'icons/turf/open_space.dmi', icon_state = "no_ceiling", layer = OVERTURF_LAYER) + no_ceiling_image = image(icon = 'icons/turf/open_space.dmi', icon_state = "no_ceiling") no_ceiling_image.plane = PLANE_MESONS /turf/simulated/floor/update_icon(var/update_neighbors) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 21fd9492f09..e5bb57ad9e8 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -252,7 +252,7 @@ O.icon_state = "2" O.anchored = 1 O.density = 1 - O.layer = 5 + O.plane = ABOVE_PLANE if(girder_material.integrity >= 150 && !girder_material.is_brittle()) //Strong girders will remain in place when a wall is melted. dismantle_wall(1,1) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 3aa00a20f0c..100c3b5a31c 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -1,5 +1,7 @@ /turf icon = 'icons/turf/floors.dmi' + layer = TURF_LAYER + plane = TURF_PLANE level = 1 var/holy = 0 diff --git a/code/game/turfs/unsimulated/shuttle.dm b/code/game/turfs/unsimulated/shuttle.dm index 99f5bc15bd8..cb70c6c36db 100644 --- a/code/game/turfs/unsimulated/shuttle.dm +++ b/code/game/turfs/unsimulated/shuttle.dm @@ -3,7 +3,6 @@ icon = 'icons/turf/shuttle_white.dmi' thermal_conductivity = 0.05 heat_capacity = 0 - layer = 2 /turf/unsimulated/shuttle/wall name = "wall" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index a31748d676d..08b16efa602 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -7,6 +7,7 @@ var/global/floorIsLava = 0 /proc/message_admins(var/msg) msg = "ADMIN LOG: [msg]" //log_adminwarn(msg) //log_and_message_admins is for this + for(var/client/C in admins) if((R_ADMIN|R_MOD) & C.holder.rights) C << msg diff --git a/code/modules/blob2/blobs/base_blob.dm b/code/modules/blob2/blobs/base_blob.dm index ba9f41c4036..19461e68c81 100644 --- a/code/modules/blob2/blobs/base_blob.dm +++ b/code/modules/blob2/blobs/base_blob.dm @@ -285,7 +285,8 @@ var/list/blobs = list() name = "blob" desc = "The blob lashing out at something." icon_state = "blob_attack" - layer = 5.2 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER time_to_die = 6 alpha = 140 mouse_opacity = 0 diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 3c3f1fd1947..568cf8f44f1 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -47,7 +47,7 @@ mob/living/carbon/proc/handle_hallucinations() if(!H.r_store) slots_free += ui_storage2 if(slots_free.len) halitem.screen_loc = pick(slots_free) - halitem.layer = 50 + halitem.hud_layerise() switch(rand(1,6)) if(1) //revolver halitem.icon = 'icons/obj/gun.dmi' diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index f08f28d97a0..c35d4b489a6 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -51,7 +51,6 @@ density = 0 icon = 'icons/obj/hydroponics_growing.dmi' icon_state = "bush4-1" - layer = 3 pass_flags = PASSTABLE mouse_opacity = 2 @@ -192,12 +191,12 @@ icon_state = "[seed.get_trait(TRAIT_PLANT_ICON)]-[growth]" if(growth>2 && growth == max_growth) - layer = 5 + plane = ABOVE_PLANE set_opacity(1) if(!isnull(seed.chems["woodpulp"])) density = 1 else - layer = 3 + reset_plane_and_layer() density = 0 /obj/effect/plant/proc/calc_dir() diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm index cade937bfb2..5e97aa68185 100644 --- a/code/modules/lighting/lighting_overlay.dm +++ b/code/modules/lighting/lighting_overlay.dm @@ -5,7 +5,6 @@ simulated = 0 anchored = 1 icon = LIGHTING_ICON - layer = LIGHTING_LAYER plane = PLANE_LIGHTING //invisibility = INVISIBILITY_LIGHTING color = LIGHTING_BASE_MATRIX diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 246d7c16a33..2b9340192fa 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -8,7 +8,7 @@ desc = "It's a g-g-g-g-ghooooost!" //jinkies! icon = 'icons/mob/ghost.dmi' icon_state = "ghost" - layer = 3.9 //Just below normal mobs + layer = BELOW_MOB_LAYER plane = PLANE_GHOSTS alpha = 127 stat = DEAD diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 4d01759ce97..7153c0fe261 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -302,11 +302,6 @@ else adverb = " a very lengthy message" message = "[speaker] [verb][adverb]." - if(src.status_flags & PASSEMOTES) - for(var/obj/item/weapon/holder/H in src.contents) - H.show_message(message) - for(var/mob/living/M in src.contents) - M.show_message(message) src.show_message(message) /mob/proc/hear_sleep(var/message) diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index 973757df64f..3a19eee319f 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -139,7 +139,6 @@ var/list/holder_mob_icon_cache = list() grabber << "You scoop up \the [src]!" src << "\The [grabber] scoops you up!" - grabber.status_flags |= PASSEMOTES H.sync(src) return H diff --git a/code/modules/mob/living/carbon/alien/diona/diona_powers.dm b/code/modules/mob/living/carbon/alien/diona/diona_powers.dm index 614647993b7..585b421c7ff 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona_powers.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona_powers.dm @@ -33,7 +33,6 @@ if(!istype(H) || !src || !(src.Adjacent(H))) return 0 H << "You feel your being twine with that of \the [src] as it merges with your biomass." - H.status_flags |= PASSEMOTES src << "You feel your being twine with that of \the [H] as you merge with its biomass." loc = H verbs += /mob/living/carbon/alien/diona/proc/split @@ -66,4 +65,3 @@ for(var/atom/A in M.contents) if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder)) return - M.status_flags &= ~PASSEMOTES \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index c55ebee9eff..dc3a01527f9 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1563,8 +1563,9 @@ /mob/living/carbon/human/proc/update_icon_special() //For things such as teshari hiding and whatnot. if(status_flags & HIDING) // Hiding? Carry on. - if(stat == DEAD || paralysis || weakened || stunned) //stunned/knocked down by something that isn't the rest verb? Note: This was tried with INCAPACITATION_STUNNED, but that refused to work. - status_flags &= ~HIDING //No hiding for you. Mob layer should be updated naturally, but it actually isn't. + if(stat == DEAD || paralysis || weakened || stunned || restrained()) //stunned/knocked down by something that isn't the rest verb? Note: This was tried with INCAPACITATION_STUNNED, but that refused to work. + reset_plane_and_layer() + status_flags &= ~HIDING else layer = HIDING_LAYER diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 471841049da..8a9db8a349d 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -279,20 +279,3 @@ to_chat(src, "Your regeneration is interrupted!") nutrition -= 75 active_regen = FALSE - -/mob/living/carbon/human/proc/hide_humanoid() - set name = "Hide" - set desc = "Allows you to hide beneath tables or certain items. Toggled on or off." - set category = "Abilities" - - if(stat == DEAD || paralysis || weakened || stunned || restrained()) // No hiding if you're stunned! - return - - if(status_flags & HIDING) - layer = MOB_LAYER - to_chat(src, "You have stopped hiding.") - else - layer = HIDING_LAYER //Just above cables with their 2.44 - to_chat(src, "You are now hiding.") - - status_flags ^= HIDING diff --git a/code/modules/mob/living/carbon/human/species/station/seromi.dm b/code/modules/mob/living/carbon/human/species/station/seromi.dm index 72f4f808d40..a8b39251582 100644 --- a/code/modules/mob/living/carbon/human/species/station/seromi.dm +++ b/code/modules/mob/living/carbon/human/species/station/seromi.dm @@ -114,7 +114,7 @@ inherent_verbs = list( /mob/living/carbon/human/proc/sonar_ping, - /mob/living/carbon/human/proc/hide_humanoid + /mob/living/proc/hide ) /datum/species/teshari/equip_survival_gear(var/mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index 5fdea4a0e6f..31fe6b3152d 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -6,7 +6,8 @@ var/is_adult = 0 speak_emote = list("chirps") - layer = 5 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER maxHealth = 150 health = 150 gender = NEUTER diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 21298e94db9..3892f8310e1 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -13,7 +13,6 @@ var/mutable_appearance/dsma = new(dsoverlay) //Changing like ten things, might as well. dsma.alpha = 0 dsma.plane = PLANE_LIGHTING - dsma.layer = LIGHTING_LAYER + 0.1 dsma.blend_mode = BLEND_ADD dsoverlay.appearance = dsma @@ -836,7 +835,6 @@ default behaviour is: for(var/atom/A in M.contents) if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder)) return - M.status_flags &= ~PASSEMOTES else if(istype(H.loc,/obj/item/clothing/accessory/holster)) var/obj/item/clothing/accessory/holster/holster = H.loc diff --git a/code/modules/mob/living/living_powers.dm b/code/modules/mob/living/living_powers.dm index d2c2d72e4e8..1442c80f9ba 100644 --- a/code/modules/mob/living/living_powers.dm +++ b/code/modules/mob/living/living_powers.dm @@ -6,9 +6,12 @@ if(stat == DEAD || paralysis || weakened || stunned || restrained()) return - if(layer == HIDING_LAYER) - layer = MOB_LAYER - src << text("You have stopped hiding.") + if(status_flags & HIDING) + status_flags &= ~HIDING + reset_plane_and_layer() + to_chat(src,"You have stopped hiding.") else + status_flags |= HIDING layer = HIDING_LAYER //Just above cables with their 2.44 - src << text("You are now hiding.") + plane = OBJ_PLANE + to_chat(src,"You are now hiding.") diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 9e4ede05a13..4b4edeb25c4 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -371,8 +371,11 @@ proc/get_radio_key_from_channel(var/channel) return 1 /mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language) - for (var/mob/O in viewers(src, null)) - O.hear_signlang(message, verb, language, src) + var/list/potentials = get_mobs_and_objs_in_view_fast(src, world.view) + var/list/mobs = potentials["mobs"] + for(var/hearer in mobs) + var/mob/M = hearer + M.hear_signlang(message, verb, language, src) return 1 /obj/effect/speech_bubble diff --git a/code/modules/mob/living/simple_animal/borer/borer.dm b/code/modules/mob/living/simple_animal/borer/borer.dm index b89e2f2af67..e4add4d7497 100644 --- a/code/modules/mob/living/simple_animal/borer/borer.dm +++ b/code/modules/mob/living/simple_animal/borer/borer.dm @@ -168,9 +168,6 @@ host.reset_view(null) host.machine = null - - var/mob/living/H = host - H.status_flags &= ~PASSEMOTES host = null return diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm index 311b013ef86..b75da20cc4d 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_powers.dm @@ -104,7 +104,6 @@ M << "Something disgusting and slimy wiggles into your ear!" src.host = M - src.host.status_flags |= PASSEMOTES src.forceMove(M) //Update their traitor status. diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index cdc6b6af745..7e012c71a0f 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -1,6 +1,7 @@ /mob density = 1 - layer = 4.0 + layer = MOB_LAYER + plane = MOB_PLANE animate_movement = 2 flags = PROXMOVE var/datum/mind/mind diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 58c530d06cf..b5cc72fd199 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -31,7 +31,6 @@ var/force_down //determines if the affecting mob will be pinned to the ground var/dancing //determines if assailant and affecting keep looking at each other. Basically a wrestling position - layer = 21 abstract = 1 item_state = "nothing" w_class = ITEMSIZE_HUGE @@ -194,7 +193,7 @@ return var/shift = 0 var/adir = get_dir(assailant, affecting) - affecting.layer = 4 + affecting.layer = MOB_LAYER switch(state) if(GRAB_PASSIVE) shift = 8 @@ -217,7 +216,7 @@ switch(adir) if(NORTH) animate(affecting, pixel_x = 0, pixel_y =-shift, 5, 1, LINEAR_EASING) - affecting.layer = 3.9 + affecting.layer = BELOW_MOB_LAYER if(SOUTH) animate(affecting, pixel_x = 0, pixel_y = shift, 5, 1, LINEAR_EASING) if(WEST) @@ -396,7 +395,7 @@ /obj/item/weapon/grab/Destroy() animate(affecting, pixel_x = 0, pixel_y = 0, 4, 1, LINEAR_EASING) - affecting.layer = 4 + affecting.reset_plane_and_layer() if(affecting) affecting.grabbed_by -= src affecting = null diff --git a/code/modules/mob/mob_planes.dm b/code/modules/mob/mob_planes.dm index 1252ed6649f..563f4339262 100644 --- a/code/modules/mob/mob_planes.dm +++ b/code/modules/mob/mob_planes.dm @@ -135,7 +135,6 @@ //Lighting is weird and has matrix shenanigans. Think of this as turning on/off darkness. /obj/screen/plane_master/fullbright plane = PLANE_LIGHTING - layer = LIGHTING_LAYER+1 color = null //To break lighting when visible (this is sorta backwards) alpha = 0 //Starts full opaque invisibility = 101 diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 9e090c2095c..816b62a099a 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -13,7 +13,8 @@ w_class = ITEMSIZE_TINY throw_range = 1 throw_speed = 1 - layer = 4 + plane = MOB_PLANE + layer = MOB_LAYER pressure_resistance = 1 slot_flags = SLOT_HEAD body_parts_covered = HEAD diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index 23ac5ace63e..2e3bfb2f797 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -8,7 +8,8 @@ w_class = ITEMSIZE_SMALL throw_range = 2 throw_speed = 1 - layer = 4 + plane = MOB_PLANE + layer = MOB_LAYER pressure_resistance = 1 attack_verb = list("bapped") var/page = 1 // current page diff --git a/code/modules/power/fusion/core/core_field.dm b/code/modules/power/fusion/core/core_field.dm index ef1c3716fae..1efb09d777b 100644 --- a/code/modules/power/fusion/core/core_field.dm +++ b/code/modules/power/fusion/core/core_field.dm @@ -9,7 +9,8 @@ icon = 'icons/obj/machines/power/fusion.dmi' icon_state = "emfield_s1" alpha = 50 - layer = 4 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER light_color = "#cc7700" var/size = 1 diff --git a/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm b/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm index 468f24510ae..29d93620151 100644 --- a/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm +++ b/code/modules/power/fusion/fuel_assembly/fuel_assembly.dm @@ -2,7 +2,6 @@ name = "fuel rod assembly" icon = 'icons/obj/machines/power/fusion.dmi' icon_state = "fuel_assembly" - layer = 4 var/material_name diff --git a/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm b/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm index 6a0f1bc205f..375af68696d 100644 --- a/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm +++ b/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm @@ -4,7 +4,6 @@ icon_state = "fuel_compressor1" density = 1 anchored = 1 - layer = 4 circuit = /obj/item/weapon/circuitboard/fusion_fuel_compressor diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 6de14313f1a..f80454d9bda 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -16,7 +16,8 @@ icon = 'icons/obj/lighting.dmi' icon_state = "tube-construct-stage1" anchored = 1 - layer = 5 + plane = MOB_LAYER + layer = ABOVE_MOB_LAYER var/stage = 1 var/fixture_type = "tube" var/sheets_refunded = 2 @@ -132,7 +133,8 @@ icon = 'icons/obj/lighting.dmi' icon_state = "bulb-construct-stage1" anchored = 1 - layer = 5 + plane = MOB_LAYER + layer = ABOVE_MOB_LAYER stage = 1 fixture_type = "bulb" sheets_refunded = 1 @@ -143,7 +145,6 @@ icon = 'icons/obj/lighting.dmi' icon_state = "flamp-construct-stage1" anchored = 0 - layer = OBJ_LAYER stage = 1 fixture_type = "flamp" sheets_refunded = 2 @@ -156,7 +157,8 @@ icon_state = "tube1" desc = "A lighting fixture." anchored = 1 - layer = 5 // They were appearing under mobs which is a little weird - Ostaf + plane = MOB_LAYER + layer = ABOVE_MOB_LAYER use_power = 2 idle_power_usage = 2 active_power_usage = 20 diff --git a/code/modules/power/sensors/powernet_sensor.dm b/code/modules/power/sensors/powernet_sensor.dm index d082b179223..20c8837b32d 100644 --- a/code/modules/power/sensors/powernet_sensor.dm +++ b/code/modules/power/sensors/powernet_sensor.dm @@ -12,7 +12,7 @@ desc = "Small machine which transmits data about specific powernet" anchored = 1 density = 0 - layer = 2.46 // Above cables, but should be below floors. + layer = ABOVE_UTILITY icon = 'icons/obj/objects.dmi' icon_state = "floor_beacon" // If anyone wants to make better sprite, feel free to do so without asking me. diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 246dbba6c7e..75ec8fffc7c 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -7,7 +7,7 @@ icon_state = "singularity_s1" anchored = 1 density = 1 - layer = 6 + plane = ABOVE_PLANE light_range = 6 unacidable = 1 //Don't comment this out. diff --git a/code/modules/power/terminal.dm b/code/modules/power/terminal.dm index a1f2fbf030e..2c01476a7a8 100644 --- a/code/modules/power/terminal.dm +++ b/code/modules/power/terminal.dm @@ -8,10 +8,10 @@ icon_state = "term" desc = "It's an underfloor wiring terminal for power equipment." level = 1 - layer = TURF_LAYER var/obj/machinery/power/master = null anchored = 1 - layer = 2.6 // a bit above wires + plane = PLATING_PLANE + layer = WIRES_LAYER+0.01 /obj/machinery/power/terminal/New() diff --git a/code/modules/projectiles/effects.dm b/code/modules/projectiles/effects.dm index ba6a749ebee..18010d3d173 100644 --- a/code/modules/projectiles/effects.dm +++ b/code/modules/projectiles/effects.dm @@ -1,7 +1,7 @@ /obj/effect/projectile icon = 'icons/effects/projectiles.dmi' icon_state = "bolt" - layer = 20 + plane = ABOVE_PLANE /obj/effect/projectile/New(var/turf/location) if(istype(location)) diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 1ac48546f5e..3587e2f36ae 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -281,7 +281,6 @@ name = "All-In-One Grinder" icon = 'icons/obj/kitchen.dmi' icon_state = "juicer1" - layer = 2.9 density = 0 anchored = 0 use_power = 1 diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index 2933ee97277..0048cd51948 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -6,7 +6,8 @@ icon_state = "conveyor0" name = "conveyor belt" desc = "A conveyor belt." - layer = 2 // so they appear under stuff + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER anchored = 1 circuit = /obj/item/weapon/circuitboard/conveyor var/operating = 0 // 1 if running forward, -1 if backwards, 0 if off diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index e9b59dd14fb..fdae51e6476 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -663,7 +663,7 @@ var/dpdir = 0 // bitmask of pipe directions dir = 0 // dir will contain dominant direction for junction pipes var/health = 10 // health points 0-10 - layer = 2.3 // slightly lower than wires and other pipes + layer = DISPOSAL_LAYER // slightly lower than wires and other pipes var/base_icon_state // initial icon state on map var/sortType = "" var/subtype = 0 diff --git a/code/modules/shieldgen/energy_field.dm b/code/modules/shieldgen/energy_field.dm index e558a2621e2..023d5fee95f 100644 --- a/code/modules/shieldgen/energy_field.dm +++ b/code/modules/shieldgen/energy_field.dm @@ -15,7 +15,8 @@ icon_state = "shield" alpha = 100 anchored = 1 - layer = 4.1 //just above mobs + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER density = 0 var/obj/machinery/shield_gen/my_gen = null var/strength = 0 // in Renwicks diff --git a/code/modules/spells/aoe_turf/conjure/conjure.dm b/code/modules/spells/aoe_turf/conjure/conjure.dm index 1302513bfeb..e96985e9bb3 100644 --- a/code/modules/spells/aoe_turf/conjure/conjure.dm +++ b/code/modules/spells/aoe_turf/conjure/conjure.dm @@ -56,7 +56,8 @@ How they spawn stuff is decided by behaviour vars, which are explained below animation.density = 0 animation.anchored = 1 animation.icon = 'icons/effects/effects.dmi' - animation.layer = 3 + animation.plane = OBJ_PLANE + animation.layer = ABOVE_JUNK_LAYER animation.master = summoned_object for(var/varName in newVars) diff --git a/code/modules/spells/targeted/ethereal_jaunt.dm b/code/modules/spells/targeted/ethereal_jaunt.dm index e48db592ad6..68cf35e9a4c 100644 --- a/code/modules/spells/targeted/ethereal_jaunt.dm +++ b/code/modules/spells/targeted/ethereal_jaunt.dm @@ -26,7 +26,8 @@ animation.density = 0 animation.anchored = 1 animation.icon = 'icons/mob/mob.dmi' - animation.layer = 5 + animation.plane = MOB_PLANE + animation.layer = ABOVE_MOB_LAYER animation.master = holder target.ExtinguishMob() if(target.buckled) diff --git a/code/modules/tables/flipping.dm b/code/modules/tables/flipping.dm index 670edd01d86..5de58c13546 100644 --- a/code/modules/tables/flipping.dm +++ b/code/modules/tables/flipping.dm @@ -84,7 +84,8 @@ set_dir(direction) if(dir != NORTH) - layer = 5 + plane = MOB_PLANE + layer = ABOVE_MOB_LAYER climbable = 0 //flipping tables allows them to be used as makeshift barriers flipped = 1 flags |= ON_BORDER @@ -102,7 +103,7 @@ verbs -=/obj/structure/table/proc/do_put verbs +=/obj/structure/table/verb/do_flip - layer = initial(layer) + reset_plane_and_layer() flipped = 0 climbable = initial(climbable) flags &= ~ON_BORDER diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm index 003535a5907..b32af0f479e 100644 --- a/code/modules/tables/tables.dm +++ b/code/modules/tables/tables.dm @@ -6,7 +6,7 @@ density = 1 anchored = 1 climbable = 1 - layer = 2.8 + layer = UNDER_JUNK_LAYER throwpass = 1 surgery_odds = 66 var/flipped = 0 diff --git a/code/modules/turbolift/turbolift_console.dm b/code/modules/turbolift/turbolift_console.dm index f6619516816..bc6bafbe529 100644 --- a/code/modules/turbolift/turbolift_console.dm +++ b/code/modules/turbolift/turbolift_console.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/turbolift.dmi' anchored = 1 density = 0 - layer = 4 + plane = MOB_PLANE var/datum/turbolift/lift diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index e4a402188a3..f3a9dab0413 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -181,7 +181,8 @@ var/list/ventcrawl_machinery = list( for(var/datum/pipeline/pipeline in network.line_members) for(var/obj/machinery/atmospherics/A in (pipeline.members || pipeline.edges)) if(!A.pipe_image) - A.pipe_image = image(A, A.loc, layer = 20, dir = A.dir) + A.pipe_image = image(A, A.loc, dir = A.dir) + A.pipe_image.plane = PLANE_LIGHTING_ABOVE pipes_shown += A.pipe_image client.images += A.pipe_image if(client) diff --git a/code/modules/xenoarcheaology/artifacts/gigadrill.dm b/code/modules/xenoarcheaology/artifacts/gigadrill.dm index 42c7288d2d9..b6c665cb661 100644 --- a/code/modules/xenoarcheaology/artifacts/gigadrill.dm +++ b/code/modules/xenoarcheaology/artifacts/gigadrill.dm @@ -7,7 +7,7 @@ var/drill_time = 10 var/turf/drilling_turf density = 1 - layer = 3.1 //to go over ores + layer = ABOVE_JUNK_LAYER /obj/machinery/giga_drill/attack_hand(mob/user as mob) if(active) diff --git a/icons/obj/cryogenics_split.dmi b/icons/obj/cryogenics_split.dmi index a25513a1435115e084811064ce7f52c734469fab..86ef62b6f8c3e5387cc4cbabd491feeeffc082bd 100644 GIT binary patch literal 3328 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 KMNUMnLSTZjFm3Pv literal 5537 zcmYjV1ys}B`~Qv_BP0bxq+uW-Al)&L8YK-%C@}*N16~|#j1UP4X_S;2AR#r$36cs( zDlbS&gClexZ2$4T|M#5V_ndE>&wcKF@;>)@zR#^Jt}!$4G5`R;Y+?+vp}f&&H$5HY z*`@6{#Y)~fnZo!ExMP#* z>F#l)jEr{d&M&*en}QZ*x>nMf>u>1jGi$Y($4qJoeR-u?+cbfQ?sj6$NoX5JFw4XH zbqjx5Owr2UH;9D6x4254Iqfn(f)5E`;%46|b=NzUu!zFME?Ympf7cB)vaD7VJQ=d9 zaPRx6$6)BRWerT@a#=y?mDRN&~M=N`j+C!iFD`21G~p2v!O#re-6m6 z&3+$|JIV_Rgm`Lq=RLNAI@-V))vrFfibj45U`5)(R6iMT(yH>EE5l+-9qi6Cb*+&l zV~xzrMC|L8@nc_OqmQ{}-v0e#}31n+Gpx-Pk6+T^8W{Ts3l!depDOTvXG_w-ac z{oYKXxo49gtku(cU~T5q9B+!oqB9OkKL^E8VzM6NraMR)T2? z4Zv!69%+kVy&l^FQU0)VoN>Kf4CL7w>3FYw5R`AJ&l4TqwIFvRvTK22nKQ;X*XK*N z!g+jPPh{(SjyqIg0`;%?{8Pz4d$y&M-D3abEy&9ezUq3X*GX?uEfG|0?Uc0qlKR2@ z2G*RmaHRx0Gf373>SUa4=wBytzatqP?Y5EW90n*ZKp)dVd3j&6!uSczG_j^b#xG?s zu1q)}wouT-CMAj;V5Z>Ku?0h)^WVOZT%-G%pudR#VxyYAlzsxU)tH3nJvn&v5BNT5%ZH35qb?5c3g>(ym5tr|kAU5>`;hB$huuW{k=E zo@R_KV{nz_UT$WJE+~-L-z`R{KM3zyMfQjCwvu!7H*d0i-8bKDoFgyv&FgP=1UZmo z=FT0Z8|eD`S5Hn%L|IAD06#<8eAjSdyK$?hbJ=?q78bJQlm1bmU>24iIgOcI{uxLP z(68UW?*aiw?}q1}v@9Hk;OnGSUtE<`%p><8F@p0yT6U;_R^rSyb(dx4}w^if^O@fM#nQ?~+mwQ1Be0CA7{K69~FJ z!yS3#kOVuruPqR-5SZ*vkzu-Ag%qzYH{aw8Gz@xx6Uk(Kr=Z4=}b7rkK+zF z4*6NspV~Wn-`PJJeZfXcEw@tfJ6I4_1OO#Nw0`4mBed)*vQ@=l@U{K^)v%daTEPOxy*`l`o5|K4b#CzzDmAb1Bn6tvn@wCYm$rTVedWZm z`S){DdD#q%qX?S7jdc}qRD@>Y#O9>u!DezLcl}wK{#F{axR@qC*;?1T(WX)5KwN&kR3fW0FVM?H z4Z>(93Jx2@L+FoIpQkv7iE9!&`RpI%_BJ_y*{;jtqjK`qdIYCJBg>yljwmMl`t`&d z4lgJu0M$A&eg6E}*WbUlp_9qkrOmNz!@F|pJ(H4lLeBdZ!k$#rY~~%k>56$qpW$`# z6cp8_r4>@`4r}X;a1@na7nZq%HX-!vDZnpZ$0x*P<{)&fkK=h?~_(k1ZUf5eiN-&nq*Ef>v!r%0Lg>v@ItDch{ zT-=zbm~a10m5Gjcfbn=WQctEG?d>@a~e5!@~{6IA>ZLAtHG;?wM+RfsD<&hQ7`h zd7^uwh9mM3V7_xuR|}QwoN2+{C3@OhYSkUi1;2qvnx2;+vTF9{K`I$ zMPCu?-_xt5K%(Big6x~TL#UGwSfMr<<`G+9{j#%7mGXiuyF@RhJPC$Q9AKqoPN9#% zMDtXyA$X!eU2^Xqz?id=CpFI<99owzJ+2teC>cScT;~FdnTI3y?Au@59;EwmNzAjA zN~pwLR$8!UFovM;;hlU8CR3>p=by-ocfMvAN?SSpz9`J$f=>c$J}EynxIZm z?l_&{RxYw7R3zpDNOwX}0vl`WIG!M6Vg~)wt^Iu=Ku{g3H>Nn7t>WYvDwJOlt_Qc+QUvtPzf^f#i2ibaF~&o*HUmm}fD}DfYVhT`^+hTLkp$p~ zSX%8=M9O*t<(DMyZTQo1cj@qV=B)}(fkabDvuT$2Ylifg!i#z~oKZ45f8%piLsLa& zwS@Gg#k*FpU8lcKFsB)$)dSt}N#5>o%6F{Wj2X|d@i`3HHI;1afjjzT0dHJu( z`iKByGI^(5WX2}Z(#nGKyuiGVPH4Og0*Ssu0gTQ7V!4Q`GWp<|vi6W{3F;&r-r-px zsja70yG8&t`hD-uRXyeX{WCh!?T`NH5+b{&d|?V_zSneb8ZX;Kq*>`M>;m z^cZdEgD45KX2eTo^m#@j3jRb}JPLN;RAfqZ39AD4 z0WC`$sb&<0TxT=YR;K9PL1)l)3Y2~Z9WDPa^dD9H51ATA0%WK4zLbkO5);^St?UrU zN)po!#}4I`O2$%Aib*H?e1x!leaNGtw0*bst}0&~$WX0R7IT7J6d4Zz7#%-CoBuTC zy<3U3v>GDPD^WQLYiZ-3?g}i4T1SYQAl!D9d!TZKL?TVrl8AKU2`@-GNlF`pC=k^S zul<-zr0M2s%Oui74a}X4RDbncnfd{65lL8ZMzf2YMicw0>@~rd8%gK${Nl5j<3Dub zlObRVMoBOS3rHVF_iXUro^Q4Qq$IW;_Q3%p!S@w(|{i@AGq(nh00h?grKF9 zR-$leGKwfQD-ks92W$S6)Bvc|6F%sXsN{=))Zyf5?Q!}f+Q7O&m7#(CaQ->LM4>Lf zaeDXg08s|X+@D7F6L0qR#q<;|^+P{;MT&ee?CANZp8z=JOV@z=d`5j$?$Gps?4$zE zS>0|AEHXlCTHRx*;j|Lb&Fyn2H#0fXrO@ITsTLoou@y*Le#C|dGG1u4I+BmQLt~8p ze#6r5VhEW!#^%Y`CQ`_hJ^DL2-}93FUGIf|qvzMf_Xnr_=n03Hm0u>ly(P0)!0jvd z!g)b;AJ$$WL=9wVN`L5-yYvr$DPmlF((){Wp#fksqiO60m(h`lrqNXd5cZ=^yN$

yhufd#zUm(F#a}Cw)y9aT}<|>PZtLZ$^%Nw*F;6(NUH(e=TmotO|vE$hz8Y zN{$wx7^J5+pp6uT!4Ul1T`ye^pam`Ustfc5RKj-BvwD7#K}$Uevt3zYBu~cn)7&moj00W= zaa}wc)m4rYj6fZ4Z>qc#2;0k>2@TTfVUVYN=mC5~7A zeZVCib#j)3W$eS0gbY}$)JOyo?%@F3$b@*`ICrg&CL8&h0 zN9UihXJ?nnfOpj%ng97bcfSkAIOqOEHuf8ip2iyU>O}RStep9%PP^>7z}$Gu)5*D5 z6zU=C6|Mbl_NneYgUOZoJ3kYLxu2f9G}v+>9kW)f0C^{>t8~=s6Jfo6Me|S*;vSn8Y@Ah zVA?{AlF*Bg%BSeddx=d{)?s*Yr>j$6#vKzme1$-2Z;YUwHw zdsi{D;)q6+f;a9@ug}@{N=n|8X@B6aM9Yu42EFy%xgmVq)$vZbP;sX$<<81{N*%h< zrK`P{Anp+-md8YGzp`=(TEj{Xu48XXwU&J;-Lm2%rdvxQ2$Be_BU^}1Qf^{}eBw?| z1}#N8&4xAgwkejo`d;-4O`+&Qch)NB|u^o0#L2qlu5 z3yP}p_5Ig;4SZaroO5z0BfYx=P=uWxTnLu=@1EPa| zN8O^IVCd7+(-4(Q3{ms{bz{l+vKe#oRFw<(#nQp8H(T6!Pv1%ie{J9y`!;z;3Sugj zml?TE^L1{ny0+per8QaD-ZAp^)OWaf`9kZ>D*)Qd>3TuADNB?-D-G!T&JOH&LhFop z#f++j`xX{-&i&?*5i7g7h4|tuPuiWxiFQHy5bZ)F25I8{+ta+EQ;~+!<$W@@EW&+e z3@SQ0nl+}wnEx><4*FFY$(rEl9m1=N0dQxuN_tR0Wdr>3K!O$>k_djSB_(sU;RuQ7 zjlqC2_a>fdvKBs{(EYDBnr`Ev&VO^}mmmPL!d5)na%g?JeDJlkF5c7*)<2$tvqoi) zLXZ_9^Db$|8pnt9nd;nBB*H6h?|6uSon+~@bw0z1Dys)KqN3EJQV5H#vAgDlpNSNI<&>CL z^fr$xzL_W;I?rIO?N0Xm6!>gie#BI*N?Rb(*LE&GG5q!k_=g)YscK@;%er6yY`QAo zW|1Xq1-=FdhJd5Yj zD>oI{k1&7tSK&|RyKc^Xe@oAljsGM0b1R$TzuS1;#S_SpH{(d`&l^dUf3ARup#|)% IzB}gs00`5OmH+?% diff --git a/maps/RandomZLevels/wildwest.dm b/maps/RandomZLevels/wildwest.dm index 51ac498fb24..90d22afb862 100644 --- a/maps/RandomZLevels/wildwest.dm +++ b/maps/RandomZLevels/wildwest.dm @@ -104,7 +104,6 @@ desc = "What is that thing?" density = 1 anchored = 1 - layer = 3 icon = 'icons/mob/critter.dmi' icon_state = "blob" var/triggerproc = "explode" //name of the proc thats called when the mine is triggered @@ -171,4 +170,4 @@ C << "You have regenerated." C.visible_message("[usr] appears to wake from the dead, having healed all wounds.") C.update_canmove() - return 1 + return 1 From 0a1e3d798b52942b4965f29d8c872a5587ddce5b Mon Sep 17 00:00:00 2001 From: elgeonmb Date: Wed, 28 Mar 2018 13:01:10 -0700 Subject: [PATCH 73/74] Lore-Compliant Oculum News Channel (#5111) * adds an e-reader full of news to the loadout * Political Almanac -> Pocket Newscaster * new news channel containing lore-compliant news that's not bad --- code/modules/economy/economy_misc.dm | 1 + code/modules/economy/lorenews.dm | 110 +++++++++++++++++++++++++ code/modules/events/event_container.dm | 1 + code/modules/events/event_dynamic.dm | 1 + polaris.dme | 1 + 5 files changed, 114 insertions(+) create mode 100644 code/modules/economy/lorenews.dm diff --git a/code/modules/economy/economy_misc.dm b/code/modules/economy/economy_misc.dm index 84a187ef91d..3ab22c662d2 100644 --- a/code/modules/economy/economy_misc.dm +++ b/code/modules/economy/economy_misc.dm @@ -92,6 +92,7 @@ var/global/economy_init = 0 news_network.CreateFeedChannel("The [using_map.starsys_name] Times", "[using_map.starsys_name] Times ExoNode - [using_map.station_short]", 1, 1) news_network.CreateFeedChannel("The Gibson Gazette", "Editor Mike Hammers", 1, 1) + news_network.CreateFeedChannel("Oculum Content Aggregator", "Oculus v6rev7", 1, 1) for(var/loc_type in typesof(/datum/trade_destination) - /datum/trade_destination) var/datum/trade_destination/D = new loc_type diff --git a/code/modules/economy/lorenews.dm b/code/modules/economy/lorenews.dm new file mode 100644 index 00000000000..63f5e024117 --- /dev/null +++ b/code/modules/economy/lorenews.dm @@ -0,0 +1,110 @@ +/datum/event/lore_news + endWhen = 10 + +/datum/event/lore_news/announce() + var/author = "Oculus v6rev7" + var/channel = "Oculum Content Aggregator" + + + //locations by region for later pick() + //probably would be good to move these to a global somehwere but fuck if I know how to do that + var/list/rim = list("Shelf", "Vounna", "Relan", "Whythe", "Angessa's Pearl") // this is also the Association list for most purposes + var/list/crescent = list("Saint Columbia", "Ganesha", "Gavel", "Oasis", "Kess-Gendar") //Vir not included + var/list/core = list("Sol", "Alpha Centauri", "Tau Ceti", "Altair") + var/list/heights = list("New Ohio", "Mahi-Mahi", "Parvati", "Sidhe", "New Seoul") + var/list/bowl = list("Zhu Que", "New Singapore", "Isavau's Gamble", "Love", "Viola", "Stove") + var/list/crypt = list("El", "Jahan's Post", "Abel's Rest", "Raphael", "Thoth", "Terminus") + var/list/weird = list("Silk", "Nyx") //no region + + //by government + var/list/solgov = crescent + core + heights + bowl + crypt + weird + var/list/skrell = list("Qerr'Vallis", "Qerma-Lakirr", "Harrqak", "Kauq'xum") + var/list/skrellfar = list("The Far Kingdom of Light and Shifting Shadow")// more colonies Elgeon + var/list/unathi = list("Moghes", "Qerrna-Qamxea", "Abel's Rest") // more colonies Anewbe + var/list/tajara = list("Rarkajar", "Mesomori", "Arathiir") + var/list/independent = list("New Kyoto", "Casini's Reach", "Ue'Orsi", "Natuna", "Neon Light") + + //this is what you should pick for most applications + //whether or not the rim goes there is something that should be changed per the metaplot + var/list/loc = solgov + skrell + tajara + + //this includes systems Sol doesn't really have eyes on + var/list/allloc = loc + unathi + skrellfar + independent + rim + + //copied right from organizations.dm + var/list/ship_names = list( + "Kestrel", + "Beacon", + "Signal", + "Freedom", + "Glory", + "Axiom", + "Eternal", + "Harmony", + "Light", + "Discovery", + "Endeavor", + "Explorer", + "Swift", + "Dragonfly", + "Ascendant", + "Tenacious", + "Pioneer", + "Hawk", + "Haste", + "Radiant", + "Luminous" + ) + + //generated based on Cerebulon's thing on the wiki + var/list/prefixes = list("IAV","ICV","IDV","IDV","IEV","IFV","IIV","ILV","IMV","IRV","ISV","ITV","SCG-A","SCG-C","SCG-D","SCG-D","SCG-E","SCG-F","SCG-I","SCG-L","SCG-M","SCG-R","SCG-S","SCG-T","BAV","BCV","BDV","BDV","BEV","BFV","BIV","BLV","BMV","BRV","BSV","BTV","HAV","HCV","HDV","HDV","HEV","HFV","HIV","HLV","HMV","HRV","HSV","HTV","MAV","MCV","MDV","MDV","MEV","MFV","MIV","MLV","MMV","MRV","MSV","MTV","NAV","NCV","NDV","NDV","NEV","NFV","NIV","NLV","NMV","NRV","NSV","NTV","VAV","VCV","VDV","VDV","VEV","VFV","VIV","VLV","VMV","VRV","VSV","VTV","WAV","WCV","WDV","WDV","WEV","WFV","WIV","WLV","WMV","WRV","WSV","WTV","XAV","XCV","XDV","XDV","XEV","XFV","XIV","XLV","XMV","XRV","XSV","XTV","ZAV","ZCV","ZDV","ZDV","ZEV","ZFV","ZIV","ZLV","ZMV","ZRV","ZSV","ZTV","GAV","GCV","GDV","GDV","GEV","GFV","GIV","GLV","GMV","GRV","GSV","GTV","AAV","ACV","ADV","ADV","AEV","AFV","AIV","ALV","AMV","ARV","ASV","ATV","LAV","LCV","LDV","LDV","LEV","LFV","LIV","LLV","LMV","LRV","LSV","LTV") + + var/datum/trade_destination/affected_dest = pick(weighted_mundaneevent_locations) //shouldn't do anything, not removing it to avoid breaking shit + //formatting breaks my fucking eyes + var/body = pick("A high-ranking Vey-Med executive was revealed to have been experimenting on biological neural enhancement techniques, believed to be of Skrellian origin, which could lead to the production of transhuman entities with an average cognitive capacity 30% greater than a baseline human.", + "[random_name(MALE)], chairman of the controversial Friends of Ned party, is scheduled to speak at a prominant university in [pick(core)] this Monday, according to a statement on his official newsfeed.", + "A wing of Ward-Takahashi B-class drones became catatonic this Thursday after tripping late-stage anti-emergence protocols. W-T Chief of Development has declined to comment.", + "A brand-new shipment of recreational voidcraft has been deemed \"Unsafe for use\" and seized at [pick(solgov)] customs. Wulf Aeronautics blames error in automated manufactory on [pick(solgov)], assures shareholders of \"One time incident\" after shares drop 4%.", + "Activity in a mostly automated Xion work-site in [pick(solgov)] has been suspended indefinitely, after reports of atypical drone behavior. The EIO's assigned investigator commented on the shutdown, saying \"We'll get them up and running again as soon as we're sure it's safe.\" No comment so far on an estimated time or date of reopening.", + "The EIO has officially raised the Emergence Threat Level in [pick(solgov)] to Blue. Citizens are reminded to comply with all EIO Agent requests. Failure to do so will be met with legal action, up to and including imprisonment.", + "All SolGov citizens beware, the scourge know as the Vox have increased the frequency of their attacks on isolated and poorly defended SolGov territories in [pick(bowl)]. Citizens have been advised to travel in groups and remain aware of their surroundings at all times.", + "The Unathi have recently moved a large amount of material into Abel's Rest, under the premise of building additional power plants. According to our sources, the material is in fact being channeled into domestic terrorist groups on both sides, in an attempt to incite a SolGov response. More news as the story develops.", + "Controversial Kishari director [random_name(FEMALE)] announced this Friday a sequel to the 2525 animated series Soldiers of the Yearlong War. Open auditions for supporting cast members have been called.", + "Amid concerns that it promotes a pro-transtech agenda, a high-profile screening of the award-winning animated film \"The Inventor's Marvelous Mechanical Maidens\" was canceled today on [pick(pick(core, heights))].", + "A radiation leak caused by a power unit rupture at a [pick(solgov)] hazardous materials reclamation plant has left several workers and neighboring residents with acute radiation poisoning. Witnesses report that a basic lifting drone failed to recognize and collided with the misplaced unit.", + "Xenophobic fringe group Humanity First has claimed credit for a bombing at a local government office on [pick(solgov)] which left three seriously injured. Police report that they have two suspects in custody, but details remain sparse.", + "Government official [random_name(MALE)] reports that the crew of the [pick(prefixes)] [pick(ship_names)], the vessel boarded by Jaguar Gang pirates earlier this week, are \"Safe, unharmed, and happy to be back at work.\" Officials were unable to comment on future security measures at this time.", + "Sanitation Technician [random_name(FEMALE)] says she was trapped in her work bathroom for three days after the locking system went haywire! The furious techie says she wants a \"hefty sum\" from her employers and that she won't be visiting that cubicle again any time soon!", + "Experts at a top university have said that almost every position in modern society might be filled by a robot within the next few decades if production continues at its current rate. Workers' Rights groups have expressed alarm at the news, and have called for protections against the \"Tin menace\".", + "An alleged cyberattack on Bishop Cybernetics systems reported to have resulted in the theft of customer data including detailed medical and biological records has been dismissed as \"Unfounded scaremongering\" by company executives.", + "[pick(crescent)] resident [random_name(FEMALE)] says she was overjoyed when her son told her he was planning to get married, but was appalled to find the bride-to-be was a common household cleaning drone! GR3TA assures us that \"Cleaning is complete.\"", + "Striking workers at a manufacturing plant on [pick(bowl)] have returned to work after news spread that plant owners would relocate operations to an automated facility if production did not resume by the end of the month. Factory investor [random_name(FEMALE)] expressed admiration at the \"Decisive action\" taken by the company.", + "Police in [pick(core)] report that they have arrested a man in connection with multinationalist fringe group Nation of Mars. Authorities were alerted when the man's ID was flagged by new screening software at the city spaceport as a known sympathizer with the violent terrorist organization.", + "The mystery of the [pick(prefixes)] [pick(ship_names)] has come to its end as a member of the vessel's skeleton crew was arrested in connection with Golden Tiger activities on the Skrell border. According to authorities, the ship - declared missing some months ago - was illegally sold to criminal elements on its way to breaking yards at [pick(heights)].", + "[random_name(MALE)] comes clean about his decade-long nightmare kept as a slave on Eutopia in a new book to be released later this year. The harried author has fought lawsuits at every turn that claim that his account is \"A work of pure fiction with an obvious leftist agenda.\"", + "Gas mask toting Revolutionary Solar People's Party extremists have reportedly attacked police at a rally in [pick(crypt)]. Peace-keeping officers were viscously pelted with objects and several protesters were found to be equipped with bottles containing an \"unknown substance.\"", + "Be careful what you say around your personal AI device as you never know who might be listening, say top minds! Cybercrime expert [random_name(FEMALE)] says hackers can easily trick your device to listen in on your conversations, record you in secret, or even steal your identity!", + "Thousands of travellers have been stranded at [pick(loc)] spaceport as a major error with the artificial intelligence system purged weeks worth of scheduling and manifest data from the port's mainframe. Major Bill's Transportation is offering stranded passengers 20% off replacement flights.", + "An outraged pet owner claims that a cybernetic company in [pick(solgov)] performed \"disturbing\" surgeries on their beloved cat, Pickles. [random_name(PLURAL)], 58 claims that the local cybernetics firm stole the furry friend from the vet's office and \"Replaced his brain with ones and zeroes.\"", + "Doctors in [pick(pick(skrell, heights))] were left in awe and horror as a Teshari was hatched with the features of an adult human man! Sources say that the youngster hatched with a full head of hair and could recite six nursery rhymes from memory. Could Skrell genetic experiments be to blame?", + "Miners in [pick(bowl)] were dismayed to discover that their boss was actually a C-class drone intelligence! \"I should've known there was something wrong,\" says dumbfounded miner [random_name(MALE)],\"I'd say good morning and he'd just start listing off mineral densities and coordinates. I just thought he loved his job a little too much.\"", + "The remains of an early 22nd century voidcraft containing \"Period artifacts, technology and human remains\" has been located on the surface of Luna after centuries of being disregarded as worthless wreck. Historians hope the find will provide insight into daily life under the short-lived Selene Federation.", + "The unexpected discovery of the remains of a what was believed to be a previously undiscovered species by workers on [pick("Nisp", "Binma", "Sif", "Kishar", "Abel's Rest", "Merelar")] has now been dismissed. Upon close analysis of the specimen, it was identified as a \"Bear with mange\", apparently dumped there some weeks prior.", + "According to a public statement by electronics giant Ward-Takahashi, many artificial intelligence systems - ranging from household appliances to industrial drones and habitat control networks - manufactured before 2550 could be at risk from a new virus dubbed \"Cap-3k\".", + "A controversial opera billed as \"The true story of Nos Amis\" has been criticized by law enforcement agencies as \"glorifying\" some of the most infamous gangsters of the 22nd century. The Polish-language \"Z Francji, do Gwiazd\" is to be distributed exclusively in Alpha Centauri for one week only.", + "Injury count continues to rise in the aftermath of the Positronic Rights Group Rally in [pick(pick(bowl, core, heights))]. Homemade teargas grenades were launched into the crowd at approximately 3:45 pm on Saturday by an unidentified person. Authorities urge anyone with information to call in, toll-free, at any time.", + "Representatives report that investigations continue on a string of fires on [pick("Nisp", "Binma", "Sif", "Kishar", "Abel's Rest", "Merelar")]. While no information has been released to the public, authorities assure the press that they are doing everything in their power to find those responsible.", + "En-route to the contentious rim system, a medical aid mission to Natuna was stopped by Ue-Katish pirates masquerading as refugees, who boarded the ship and stripped it of all supplies.", + "Lead Singer of Strawberry Idol Revealed As Three Teshari In A Trench Coat-- Newest gimmick or shocking revelation??", + "Shocking art critics throughout the system, a recent submission to the [pick(solgov)] Museum of Absurdism's contemporary exhibit was revealed to actually be the nutritional information on the back of a dehydrated cereal product common in Skrell space.", + "The celebrated magical kid series \"Petit Yuusha Jossen Temonila\" has announced its newest season at the height of its demicentenial festival. Noted director [random_name(MALE)] has promised to bring a diverse production staff to the venerable series, and has stated a theme of \"the friendships that transcend borders\".", + "The Hephaestus Industries board of directors announced this Monday the highest annual profits since the height of the Lizard Riots.", + "A radical group of Mercurials were convicted today of violations of Five Points legislature at an extraordinary court on [pick(solgov)]. These convictions come at the heels of a successful sting operation six years in the making, lead by local Head of EIO [random_name(FEMALE)].", + "An unnamed official of the shipping TSC Major Bill's Transportation narrowly escaped an attempt on their life by a deranged assassin. The assassin claims to have been driven to this henious act by the corporation's infamous jingle.", + "In the aftermath of yesterday's synthphobic rally on [pick(solgov)], three positronic citizens were left irreparably damaged by a hostile mob, who claim that the victims were \"AAs\" attempting to infiltrate the rally.", + "EIO spokesperson [random_name(MALE)] stated in a press conference yesterday that the \"Shakespear\" A-class codeline was briefly available for download on the darknet, although they claim to be \"confident that the leak was shut down before any significant portion could be downloaded\". Experts suspect Association involvement.", + "[pick("Strives Towards", "Embraces", "Dreams of", "Cultivates", "Advocates", "Exemplifies")] [pick("Strength", "Wisdom", "Independence", "Pragmatism", "Reason", "Development")], a Community Child from Angessa's Pearl, published his memoir today, detailing a shocking level of abuse by caretakers and educators.", + "Nova Sixty, Mercurial web personality, claims that the disappearence of the SCG-R Song Shi was a plot by \"extradimensional rockmen\" who intend to sow mistrust between the Association and SolGov. Quote Sixty, \"The Far Kingdoms' attempt to hide the TRUTH only proves that they and their rockman allies are NOT to be trusted.\"", + ) + + news_network.SubmitArticle(body, author, channel, null, 1) diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 37a576a4420..f75f6c0597a 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -139,6 +139,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Shipping Error", /datum/event/shipping_error , 30, list(ASSIGNMENT_ANY = 2), 0), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Space Dust", /datum/event/dust , 60, list(ASSIGNMENT_ENGINEER = 20), 0, 0, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lore News", /datum/event/lore_news, 400), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)), ) diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm index 9f8eca869c8..b1a537639de 100644 --- a/code/modules/events/event_dynamic.dm +++ b/code/modules/events/event_dynamic.dm @@ -48,6 +48,7 @@ var/list/event_last_fired = list() possibleEvents[/datum/event/economic_event] = 300 possibleEvents[/datum/event/trivial_news] = 400 possibleEvents[/datum/event/mundane_news] = 300 + possibleEvents[/datum/event/lore_news] = 300 // up this if the above ones get removed as they damn well should possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200) possibleEvents[/datum/event/money_lotto] = max(min(5, player_list.len), 50) diff --git a/polaris.dme b/polaris.dme index ec2d3c53dfe..86890735b3a 100644 --- a/polaris.dme +++ b/polaris.dme @@ -1457,6 +1457,7 @@ #include "code\modules\economy\EFTPOS.dm" #include "code\modules\economy\Events.dm" #include "code\modules\economy\Events_Mundane.dm" +#include "code\modules\economy\lorenews.dm" #include "code\modules\economy\price_list.dm" #include "code\modules\economy\retail_scanner.dm" #include "code\modules\economy\TradeDestinations.dm" From 499f6c84df8e67c9b31f3c098cc2fdbec894835b Mon Sep 17 00:00:00 2001 From: elgeonmb Date: Wed, 28 Mar 2018 13:01:29 -0700 Subject: [PATCH 74/74] prettified lorecodex, added a month's worth of news (#5112) * prettified lorecodex : added a month's worth of news * what the hell elgie * all according to kaikoku --- code/modules/lore_codex/news_data/main.dm | 37 +++++++++++++++++------ 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/code/modules/lore_codex/news_data/main.dm b/code/modules/lore_codex/news_data/main.dm index 2a59e12d5e1..2b0c7a4a81b 100644 --- a/code/modules/lore_codex/news_data/main.dm +++ b/code/modules/lore_codex/news_data/main.dm @@ -4,11 +4,13 @@ region. Each is labled by date of publication and title. This list is self-updating, and from time to time the publisher will push new \ articles. You are encouraged to check back frequently." children = list( - /datum/lore/codex/page/article1, - /datum/lore/codex/page/article2, - /datum/lore/codex/page/article3, - /datum/lore/codex/page/article4, + /datum/lore/codex/page/article7, + /datum/lore/codex/page/article6, /datum/lore/codex/page/article5, + /datum/lore/codex/page/article4, + /datum/lore/codex/page/article3, + /datum/lore/codex/page/article2, + /datum/lore/codex/page/article1, /datum/lore/codex/page/about_news, ) @@ -20,7 +22,7 @@ information, feel free to visit our homepage at oc.about.tsc, or the sites of any of our constituents." /datum/lore/codex/page/article1 - name = "08/30/61-- VGA Legalizes Prometheans; Nanotrasen Begins Manufacture and Testing" + name = "08/30/61 - VGA Legalizes Prometheans; Nanotrasen Begins Manufacture and Testing" data = "Today's meeting of the Vir Bicameral led to the passing of the Wynther-Helsey Bill, an implementation of the legal framework \ used in Aetolus to handle the production and cultivation of the Macrolimbus species dubbed \"Prometheans\". These ill-researched organisms \ possess cognitive abilities easily equaling those of A-class drones, but so far have not been included under the EIO's list of dangerous \ @@ -38,7 +40,7 @@ follow-up poll indicates that an appreciable number of Sivians do not support the framework's current implementation." /datum/lore/codex/page/article2 - name = "2/3/62-- Corporate Coup on Aetolus" + name = "2/3/62 - Corporate Coup on Aetolus" data = "A recent incident aboard the NRS Prometheus issued in a major change in the leadership of the Promethean homeworld. During \ a late-night meeting of the Nanotrasen Board of Trustees, several high-ranking personnel, including Head of Research Naomi Harper,\ announced their intention to assume direct control of Nanotrasen facilities in the system. It is known that several dissenting \ @@ -51,7 +53,7 @@ not responded to. Free Traders are recommended to stay clear of the region until the situation resolves itself." /datum/lore/codex/page/article3 - name = "2/10/62-- Aetolian Partisans Declare Independence" + name = "2/10/62 - Aetolian Partisans Declare Independence" data = "Breaking their week-long silence, the leaders of the Aetolian Coup, and their spokesperson and presumed leader Naomi Harper issued an address earlier today, delivered to the Oculum Broadcast office on Pearl by drone courier. Quote Dr. Harper: \"Our previous silence was a necessity, while we consolidated our forces and dealt with corporatists both internally and in Vounna's former Grayson outposts.\". In Harper's hour-long address, she berates the failure of SolGov to provide adequate protections for Prometheans. \"We will not let the Promethean be another positronic brain; they will not labor under a century of slavery, deprived of a state to call their own. The Luddites of the Friends and of the Icarus Front will not be permitted to decide the fate of a nascent race before it begins.\"\

\ Harper proceeded to unilaterally declare Vounna's independence from SolGov, claiming sovereignty over the system as the first Chairperson of the \"Aetolian Council\". Speaker of the Shadow Coalition ISA-5 has urged their government to treat the developing situation with caution but decried Harper's rhetoric, stating in a press release, \"While I know well the injustices visited on myself and my people by misguided forbearers, it is important to treat any emerging technology with respect. Current policies regarding the Prometheans are designed to limit risk during sociological trials on Aetolus and beyond. As for myself, I doubt the sincerity of this human who claims to speak for the Prometheans, when the Prometheans are perfectly equipped to speak for themselves.\"\ @@ -59,7 +61,7 @@ NanoTrasen is expected to redouble their Promethean research programs in the Vir system until stability is restored to Vounna." /datum/lore/codex/page/article4 - name = "2/14/62-- SCG Denounces Aetolian Coup; Mobilizes Fleet" + name = "2/14/62 - SCG Denounces Aetolian Coup; Mobilizes Fleet" data = "Dismissing claims of inaction, a spokesperson for the Solar Confederate Government today confirmed that the Colonial Assembly has voted overwhelmingly in favor of swift military action in response to the coup on Aetolus earlier this month. Icarus Front Chairperson Mackenzie West was quick to make a damning official statement: \"Dr. Harper and her radical agitators cannot be excused for their violent, despicable attempts to destabilize the flourishing economy of the Almach Rim. The ruthless murder of innocents, and illegal seizure of private property are crimes that cannot merely be met with strong words and gentle slaps to the wrist\"...\"I am proud to announce that two units of brave Solar marines have been assigned to the SCG-R Song Shi rapid response cruiser, with the full backing of the Icarus Front - and I hope with my heart, the backing of all patriotic Solar citizens.\"\

\ The decision faced resistance from more laissez faire Assembly member states, including prominent SEO governor Bruno Ofako, delaying an earlier consensus. Supporters of the action hope that this decisive display of military strength will encourage the rebels to stand down without further bloodshed, and submit to prosecution by the Lunar High Courts.\ @@ -67,7 +69,7 @@ The Icarus Front has also proposed a temporary ban on continued Promethean research, though this motion has yet to gain any traction." /datum/lore/codex/page/article5 - name = "2/23/62-- \"Almach Association\" Shocks Nation" + name = "2/23/62 - \"Almach Association\" Shocks Nation" data = "Shocking the nation, in the wee hours UTC a number of governments in the Almach Rim announced their intent to secede from the Confederacy as a unified political organization they refer to as the Almach Association, joining the already-declared Aetolian Council. Among the half-dozen affected systems is Angessa's Pearl, through which the Song Shi was passing en route to Aetolus. The Association has already issued a political manifesto and a foundational charter, leading political scientists across the galaxy to suspect back-doors collusion and possible Shelfican interference, a hypothesis made more likely by Morpheus Cyberkinetics' exonet site voicing support for the Association. Others suspect a moment of political crystallization, not unlike that in the Golden Hour three centuries ago. These researchers are already referring to this morning's events as the Gray Hour.\

\ The Association's official manifesto repudiates the Five Points, calling them \"an archaic and distinctly human invention\". Experts agree that this bold declaration puts the Movement more in line with the Golden Hour than with the Age of Secession, and many fear that nothing short of a miracle like the discovery of the positronics will spare humanity from a bloody civil war.\ @@ -75,3 +77,20 @@ While the Association currently lists only a handful of Almach Rim systems as \"Constituent Organizations\", it has named Shelf, the Free Relan Federation, and the Eutopian Foreign Relations Board as \"observers\". The implications of this status are yet to be identified.\

\ The fate of the SCG-R Song Shi and her crew remain unknown." + +/datum/lore/codex/page/article6 + name = "3/03/62 - A Week Out From Almach: What are the facts?" + data = "* Several organizations in the Almach Rim, including Angessa's Pearl, the Aetolian Council, the Interstellar Workers of Wythe, the Republic of Whitney, and members of several prominent families in the Neon Light unilaterally declared secession from SCG.

*This secession was first called the Grey Hour by political scientists in New Florence, a term popularized by reporter Elspor Fong.

* Shelf, the FRF, and the EFRB were declared \"observers\" in the Almach Association charter.

* None of these organizations have issued a statement on the matter.

* The SCG-R Song Shi was stranded in the region during the secession.

* SolGov has not issued an official statement of the fate of the Song Shi.

* Several confederate agencies, including Emergent Intelligence Oversight, the Trade and Customs Bureau, and SCG Fleet Intelligence have declared a \"state of emergency\".

* SolGov itself has NOT declared a state of emergency.

* Legitimate communications in and out of the Almach Rim are restricted to audited text messages for the period.

* Several illegitimate communication links exist and are believed by Fleet Intelligence to be currently hosting the official sites for Morpheus Cyberkinetics and for the Association itself.

* Icarus Front chairperson Mackenzie West has proposed a moratorium on the creation of new Prometheans for the duration of the crisis.

* Local laws on the subject will apply until the Assembly meets late in May.

* No confederate lawmaker has proposed action against Relani, Shelfican, or newly Almachi nationals living within stable regions.

* The border remains tightly closed to migrants, media, and diplomats alike." + +/datum/lore/codex/page/article7 + name = "3/21/62 - Relan, Shelf Join the Almach Association" + data = "Recent reports from within the Association indicate that the Free Relan Federation and Shelf have officially decided to join the Almach Association. President Nia Fischer of the FRF had this to say on the matter, in a speech addressed to the population at large. \ +

\ + \ + \"Our decision to join the Association may, at first, seem strange. It is true that we have much to gain from trade with the Solars, and that the radical transhumanism of Angessa's Pearl is not our way. But I will remind you that it was Shelf, not Sol, who ensured our prosperity just over two decades ago-- who safeguarded our independence and prevented us from falling to barbarism and dictatorship. We owe it, not just to Shelf but to all the members of the Almach Rim, to support their independence just the same. And that, my fellow Relanians, is the crux of it all. The Association is a revolution, at the heart of it all, and many of the now-independent states were owned near-outright by Trans-Stellar Corporations until the Association allowed them to shake out their fetters. What right do we have to sit by while just a dozen light-years coreward newly-born republics suffer the growing pains of independence? What right do we have to bask in our own stability when our neighbors, our comrades in ideology, are struggling with a cruel blockade proposed by politicians back on Earth and Luna? That is why we must join with them, guard them, and guide them, for as long as need be.\"\ +

\ + \ + A Shelfican spokesperson, meanwhile, had only this to say:\ +

\ + \"We're probably going to regret this but, y'know, the whole thing is kind of our fault. Sure, whatever.\"" +