From a905c15dade044be6c4a68d82713b161c6fa0f2f Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 08:18:35 -0500 Subject: [PATCH 01/15] Replaces /image with /mutable_appearance (#556) * Replaces /image with /mutable_appearance, where appropriate * Update miscellaneous.dm * Delete miscellaneous.dm.rej * Delete pet.dm.rej * Update pet.dm * Update species.dm * Update miscellaneous.dm * Update species.dm * Update miscellaneous.dm * Delete species.dm.rej * Update species.dm pretty sure I got all the indentation correct THIS time, ffs * Update species.dm * Update species.dm fucking tabs man, fucking tabs. --- code/__HELPERS/icon_smoothing.dm | 30 +- code/__HELPERS/unsorted.dm | 8 +- code/_onclick/hud/action_button.dm | 3 +- code/_onclick/hud/parallax.dm | 6 +- code/_onclick/hud/screen_objects.dm | 17 +- .../subsystem/processing/overlays.dm | 10 +- code/datums/action.dm | 6 +- code/datums/antagonists/datum_clockcult.dm | 2 +- code/datums/dog_fashion.dm | 4 +- code/datums/mutable_appearance.dm | 18 + code/datums/mutations.dm | 14 +- code/game/gamemodes/blob/blobs/blob_mobs.dm | 6 +- code/game/gamemodes/blob/blobs/core.dm | 9 +- code/game/gamemodes/blob/blobs/node.dm | 9 +- .../clock_structures/geis_binding.dm | 3 +- .../ratvar_the_clockwork_justicar.dm | 2 +- .../clock_structures/tinkerers_daemon.dm | 11 +- code/game/gamemodes/cult/cult_items.dm | 6 +- code/game/gamemodes/cult/runes.dm | 10 +- .../gamemodes/devil/true_devil/inventory.dm | 15 +- code/game/gamemodes/nuclear/nuclearbomb.dm | 28 +- code/game/machinery/computer/apc_control.dm | 9 +- code/game/machinery/computer/message.dm | 4 +- code/game/machinery/doors/airlock.dm | 20 +- code/game/machinery/doors/brigdoors.dm | 2 +- code/game/machinery/iv_drip.dm | 20 +- code/game/machinery/status_display.dm | 4 +- code/game/machinery/vending.dm | 2 +- code/game/machinery/washing_machine.dm | 2 +- code/game/mecha/mecha_wreckage.dm | 2 +- code/game/mecha/working/ripley.dm | 4 +- .../effects/decals/cleanable/humans.dm | 24 +- code/game/objects/items.dm | 2 +- code/game/objects/items/crayons.dm | 9 +- code/game/objects/items/devices/PDA/PDA.dm | 26 +- code/game/objects/items/devices/aicard.dm | 4 +- code/game/objects/items/devices/flashlight.dm | 5 +- code/game/objects/items/robot/robot_items.dm | 2 +- code/game/objects/items/shooting_range.dm | 16 +- .../objects/items/weapons/chrono_eraser.dm | 4 +- .../objects/items/weapons/cigs_lighters.dm | 18 +- code/game/objects/items/weapons/cosmetics.dm | 6 +- code/game/objects/items/weapons/explosives.dm | 6 +- .../items/weapons/grenades/ghettobomb.dm | 17 +- .../objects/items/weapons/grenades/plastic.dm | 8 +- .../objects/items/weapons/holy_weapons.dm | 2 +- .../objects/items/weapons/pneumaticCannon.dm | 2 +- .../objects/items/weapons/storage/bags.dm | 4 +- .../objects/items/weapons/storage/boxes.dm | 2 +- .../objects/items/weapons/storage/fancy.dm | 16 +- .../objects/items/weapons/storage/secure.dm | 2 +- .../objects/items/weapons/storage/toolbox.dm | 2 +- .../objects/items/weapons/tanks/watertank.dm | 4 +- code/game/objects/obj_defense.dm | 2 +- .../structures/beds_chairs/alien_nest.dm | 6 +- .../objects/structures/beds_chairs/chair.dm | 4 +- code/game/objects/structures/electricchair.dm | 2 +- code/game/objects/structures/guncase.dm | 6 +- .../structures/transit_tubes/transit_tube.dm | 16 +- code/game/objects/structures/watercloset.dm | 2 +- code/game/objects/structures/window.dm | 6 +- code/game/turfs/closed.dm | 6 +- code/game/turfs/open.dm | 17 +- code/game/turfs/simulated/minerals.dm | 15 +- code/modules/admin/verbs/pray.dm | 6 +- code/modules/assembly/holder.dm | 11 +- .../atmospherics/machinery/atmosmachinery.dm | 15 +- .../atmospherics/machinery/other/miner.dm | 9 +- code/modules/clothing/clothing.dm | 36 +- .../modules/clothing/spacesuits/chronosuit.dm | 16 - code/modules/clothing/spacesuits/hardsuit.dm | 6 +- code/modules/clothing/suits/miscellaneous.dm | 1089 ++++++++--------- code/modules/detectivework/evidence.dm | 15 +- code/modules/events/portal_storm.dm | 4 +- .../drinks/drinks/drinkingglass.dm | 12 +- .../food_and_drinks/food/customizables.dm | 41 +- code/modules/food_and_drinks/food/snacks.dm | 8 +- .../food_and_drinks/food/snacks/meat.dm | 6 +- .../food_and_drinks/food/snacks_other.dm | 4 +- .../food_and_drinks/food/snacks_pie.dm | 2 +- .../kitchen_machinery/gibber.dm | 10 +- code/modules/food_and_drinks/pizzabox.dm | 19 +- code/modules/games/cards.dm | 29 +- code/modules/holiday/easter.dm | 4 +- .../hydroponics/beekeeping/honeycomb.dm | 10 +- code/modules/hydroponics/grown/towercap.dm | 5 +- code/modules/hydroponics/hydroponics.dm | 25 +- code/modules/hydroponics/sample.dm | 6 +- code/modules/mining/equipment.dm | 20 +- code/modules/mining/fulton.dm | 12 +- code/modules/mining/lavaland/ruins/gym.dm | 7 +- code/modules/mining/ores_coins.dm | 2 +- code/modules/mob/dead/observer/observer.dm | 32 +- .../carbon/alien/humanoid/update_icons.dm | 10 +- .../modules/mob/living/carbon/alien/screen.dm | 3 +- .../carbon/alien/special/alien_embryo.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 18 +- .../mob/living/carbon/human/species.dm | 250 ++-- .../mob/living/carbon/human/update_icons.dm | 78 +- .../mob/living/carbon/monkey/update_icons.dm | 9 +- .../modules/mob/living/carbon/update_icons.dm | 36 +- code/modules/mob/living/living.dm | 4 +- code/modules/mob/living/silicon/robot/life.dm | 6 +- .../modules/mob/living/silicon/robot/robot.dm | 4 +- .../living/simple_animal/bot/construction.dm | 4 +- .../mob/living/simple_animal/bot/ed209bot.dm | 2 +- .../mob/living/simple_animal/bot/medbot.dm | 2 +- .../mob/living/simple_animal/friendly/dog.dm | 18 +- .../friendly/drone/visuals_icons.dm | 21 +- .../mob/living/simple_animal/friendly/pet.dm | 14 +- .../living/simple_animal/guardian/guardian.dm | 13 +- .../simple_animal/guardian/types/protector.dm | 6 +- .../mob/living/simple_animal/hostile/bear.dm | 4 +- .../mob/living/simple_animal/hostile/bees.dm | 24 +- .../mob/living/simple_animal/hostile/mimic.dm | 8 +- .../living/simple_animal/hostile/mushroom.dm | 16 +- .../simple_animal/hostile/retaliate/ghost.dm | 11 +- .../mob/living/simple_animal/slime/slime.dm | 2 +- code/modules/mob/mob_helpers.dm | 17 +- code/modules/paperwork/paper.dm | 4 +- code/modules/paperwork/paperbin.dm | 2 +- code/modules/paperwork/paperplane.dm | 3 +- code/modules/power/apc.dm | 45 +- code/modules/power/cell.dm | 6 +- code/modules/power/generator.dm | 4 +- code/modules/power/singularity/collector.dm | 4 +- code/modules/power/singularity/narsie.dm | 2 +- code/modules/power/smes.dm | 29 +- code/modules/power/solar.dm | 7 +- code/modules/power/turbine.dm | 10 +- code/modules/projectiles/guns/energy.dm | 11 +- .../guns/energy/kinetic_accelerator.dm | 5 +- .../chemistry/machinery/chem_dispenser.dm | 9 +- .../reagents/pyrotechnic_reagents.dm | 2 +- .../reagents/reagent_containers/bottle.dm | 2 +- .../reagents/reagent_containers/dropper.dm | 2 +- .../reagents/reagent_containers/glass.dm | 2 +- .../reagents/reagent_containers/syringes.dm | 7 +- code/modules/recycling/disposal-unit.dm | 8 +- code/modules/research/message_server.dm | 2 +- .../ruins/objects_and_mobs/necropolis_gate.dm | 2 +- code/modules/shuttle/manipulator.dm | 4 +- code/modules/spells/spell_types/lightning.dm | 7 +- code/modules/station_goals/bsa.dm | 9 +- code/modules/surgery/bodyparts/bodyparts.dm | 69 +- code/modules/surgery/bodyparts/head.dm | 45 +- .../surgery/organs/augments_internal.dm | 2 +- code/modules/vehicles/atv.dm | 6 +- code/modules/vehicles/speedbike.dm | 5 +- tgstation.dme | 1 + 151 files changed, 1379 insertions(+), 1531 deletions(-) create mode 100644 code/datums/mutable_appearance.dm diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm index d890788c91..de46e18fde 100644 --- a/code/__HELPERS/icon_smoothing.dm +++ b/code/__HELPERS/icon_smoothing.dm @@ -1,7 +1,7 @@ //generic (by snowflake) tile smoothing code; smooth your icons with this! /* - Each tile is divided in 4 corners, each corner has an image associated to it; the tile is then overlayed by these 4 images + Each tile is divided in 4 corners, each corner has an appearance associated to it; the tile is then overlayed by these 4 appearances To use this, just set your atom's 'smooth' var to 1. If your atom can be moved/unanchored, set its 'can_be_unanchored' var to 1. If you don't want your atom's icon to smooth with anything but atoms of the same type, set the list 'canSmoothWith' to null; Otherwise, put all types you want the atom icon to smooth with in 'canSmoothWith' INCLUDING THE TYPE OF THE ATOM ITSELF. @@ -44,7 +44,6 @@ #define DEFAULT_UNDERLAY_ICON 'icons/turf/floors.dmi' #define DEFAULT_UNDERLAY_ICON_STATE "plating" -#define DEFAULT_UNDERLAY_IMAGE image(DEFAULT_UNDERLAY_ICON, DEFAULT_UNDERLAY_ICON_STATE) /atom/var/smooth = SMOOTH_FALSE /atom/var/top_left_corner @@ -157,14 +156,16 @@ /turf/closed/wall/diagonal_smooth(adjacencies) adjacencies = reverse_ndir(..()) if(adjacencies) - var/list/U = list() + var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER) + var/list/U = list(underlay_appearance) if(fixed_underlay) if(fixed_underlay["space"]) - var/image/I = image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER) - I.plane = PLANE_SPACE - U += I + underlay_appearance.icon = 'icons/turf/space.dmi' + underlay_appearance.icon_state = SPACE_ICON_STATE + underlay_appearance.plane = PLANE_SPACE else - U += image(fixed_underlay["icon"], fixed_underlay["icon_state"], layer=TURF_LAYER) + underlay_appearance.icon = fixed_underlay["icon"] + underlay_appearance.icon_state = fixed_underlay["icon_state"] else var/turf/T = get_step(src, turn(adjacencies, 180)) if(T && (T.density || T.smooth)) @@ -173,15 +174,18 @@ T = get_step(src, turn(adjacencies, 225)) if(isspaceturf(T) && !istype(T, /turf/open/space/transit)) - var/image/I = image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER) - I.plane = PLANE_SPACE - U += I + underlay_appearance.icon = 'icons/turf/space.dmi' + underlay_appearance.icon_state = SPACE_ICON_STATE + underlay_appearance.plane = PLANE_SPACE else if(T && !T.density && !T.smooth) - U += T + underlay_appearance.icon = T.icon + underlay_appearance.icon_state = T.icon_state else if(baseturf && !initial(baseturf.density) && !initial(baseturf.smooth)) - U += image(initial(baseturf.icon), initial(baseturf.icon_state), layer=TURF_LAYER) + underlay_appearance.icon = initial(baseturf.icon) + underlay_appearance.icon_state = initial(baseturf.icon_state) else - U += DEFAULT_UNDERLAY_IMAGE + underlay_appearance.icon = DEFAULT_UNDERLAY_ICON + underlay_appearance.icon_state = DEFAULT_UNDERLAY_ICON_STATE underlays = U diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 35e66d5f4b..a7338a0c5d 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1138,13 +1138,13 @@ B --><-- A if(location == src) return 1 -/proc/flick_overlay_static(image/I, atom/A, duration) +/proc/flick_overlay_static(O, atom/A, duration) set waitfor = 0 - if(!A || !I) + if(!A || !O) return - A.add_overlay(I) + A.add_overlay(O) sleep(duration) - A.cut_overlay(I) + A.cut_overlay(O) /proc/get_areas_in_z(zlevel) . = list() diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index 407137dfcf..96a07bad24 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -57,8 +57,7 @@ /obj/screen/movable/action_button/hide_toggle/proc/UpdateIcon() cut_overlays() - var/image/img = image(hide_icon, src, hidden ? show_state : hide_state) - add_overlay(img) + add_overlay(mutable_appearance(hide_icon, hidden ? show_state : hide_state)) /obj/screen/movable/action_button/MouseEntered(location,control,params) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index df0894403c..4bf86f414b 100644 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -261,9 +261,9 @@ for(var/y in -count to count) if(x == 0 && y == 0) continue - var/image/I = image(icon, null, icon_state) - I.transform = matrix(1, 0, x*480, 0, 1, y*480) - new_overlays += I + var/mutable_appearance/texture_overlay = mutable_appearance(icon, icon_state) + texture_overlay.transform = matrix(1, 0, x*480, 0, 1, y*480) + new_overlays += texture_overlay cut_overlays() add_overlay(new_overlays) view_sized = view diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index b9c791a168..a3a60b1f31 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -134,21 +134,16 @@ icon_state = icon_empty /obj/screen/inventory/hand - var/image/active_overlay - var/image/handcuff_overlay - var/image/blocked_overlay + var/mutable_appearance/handcuff_overlay + var/static/mutable_appearance/blocked_overlay = mutable_appearance('icons/mob/screen_gen.dmi', "blocked") var/held_index = 0 /obj/screen/inventory/hand/update_icon() ..() - if(!active_overlay) - active_overlay = image("icon"=icon, "icon_state"="hand_active") if(!handcuff_overlay) var/state = (!(held_index % 2)) ? "markus" : "gabrielle" - handcuff_overlay = image("icon"='icons/mob/screen_gen.dmi', "icon_state"=state) - if(!blocked_overlay) - blocked_overlay = image("icon"='icons/mob/screen_gen.dmi', "icon_state"="blocked") + handcuff_overlay = mutable_appearance('icons/mob/screen_gen.dmi', state) cut_overlays() @@ -163,7 +158,7 @@ add_overlay(blocked_overlay) if(held_index == hud.mymob.active_hand_index) - add_overlay(active_overlay) + add_overlay("hand_active") /obj/screen/inventory/hand/Click(location, control, params) @@ -445,7 +440,7 @@ /obj/screen/zone_sel/update_icon(mob/user) cut_overlays() - add_overlay(image('icons/mob/screen_gen.dmi', "[selecting]")) + add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[selecting]")) user.zone_selected = selecting /obj/screen/zone_sel/alien @@ -453,7 +448,7 @@ /obj/screen/zone_sel/alien/update_icon(mob/user) cut_overlays() - add_overlay(image('icons/mob/screen_alien.dmi', "[selecting]")) + add_overlay(mutable_appearance('icons/mob/screen_alien.dmi', "[selecting]")) user.zone_selected = selecting /obj/screen/zone_sel/robot diff --git a/code/controllers/subsystem/processing/overlays.dm b/code/controllers/subsystem/processing/overlays.dm index 1a42944bb5..1aa76e6b3d 100644 --- a/code/controllers/subsystem/processing/overlays.dm +++ b/code/controllers/subsystem/processing/overlays.dm @@ -55,7 +55,7 @@ PROCESSING_SUBSYSTEM_DEF(overlays) /proc/iconstate2appearance(icon, iconstate) var/static/image/stringbro = new() - var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches + var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches var/list/cached_icon = icon_states_cache[icon] if (cached_icon) var/cached_appearance = cached_icon["[iconstate]"] @@ -91,7 +91,7 @@ PROCESSING_SUBSYSTEM_DEF(overlays) new_overlays[i] = iconstate2appearance(icon, cached_overlay) else if(isicon(cached_overlay)) new_overlays[i] = icon2appearance(cached_overlay) - else //image probable + else //image/mutable_appearance probable appearance_bro.appearance = cached_overlay if(!ispath(cached_overlay)) appearance_bro.dir = cached_overlay.dir @@ -99,11 +99,11 @@ PROCESSING_SUBSYSTEM_DEF(overlays) return new_overlays #define NOT_QUEUED_ALREADY (!(flags & OVERLAY_QUEUED)) -#define QUEUE_FOR_COMPILE flags |= OVERLAY_QUEUED; SSoverlays.processing += src; +#define QUEUE_FOR_COMPILE flags |= OVERLAY_QUEUED; SSoverlays.processing += src; /atom/proc/cut_overlays(priority = FALSE) var/list/cached_overlays = our_overlays var/list/cached_priority = priority_overlays - + var/need_compile = FALSE if(LAZYLEN(cached_overlays)) //don't queue empty lists, don't cut priority overlays @@ -165,7 +165,7 @@ PROCESSING_SUBSYSTEM_DEF(overlays) if(cut_old) cut_overlays() return - + var/list/cached_other = other.our_overlays if(cached_other) if(cut_old || !LAZYLEN(our_overlays)) diff --git a/code/datums/action.dm b/code/datums/action.dm index bd18d646e2..08239492f3 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -110,12 +110,8 @@ /datum/action/proc/ApplyIcon(obj/screen/movable/action_button/current_button) if(icon_icon && button_icon_state && current_button.button_icon_state != button_icon_state) - var/image/img - img = image(icon_icon, current_button, button_icon_state) - img.pixel_x = 0 - img.pixel_y = 0 current_button.cut_overlays(TRUE) - current_button.add_overlay(img) + current_button.add_overlay(mutable_appearance(icon_icon, button_icon_state)) current_button.button_icon_state = button_icon_state diff --git a/code/datums/antagonists/datum_clockcult.dm b/code/datums/antagonists/datum_clockcult.dm index 89be685f76..0c39b5a989 100644 --- a/code/datums/antagonists/datum_clockcult.dm +++ b/code/datums/antagonists/datum_clockcult.dm @@ -83,7 +83,7 @@ var/mob/living/silicon/ai/A = S A.can_be_carded = FALSE A.requires_power = POWER_REQ_CLOCKCULT - var/list/AI_frame = list(image('icons/mob/clockwork_mobs.dmi', A, "aiframe")) //make the AI's cool frame + var/list/AI_frame = list(mutable_appearance('icons/mob/clockwork_mobs.dmi', "aiframe")) //make the AI's cool frame for(var/d in GLOB.cardinal) AI_frame += image('icons/mob/clockwork_mobs.dmi', A, "eye[rand(1, 10)]", dir = d) //the eyes are randomly fast or slow A.add_overlay(AI_frame) diff --git a/code/datums/dog_fashion.dm b/code/datums/dog_fashion.dm index 75c8379524..c798f35218 100644 --- a/code/datums/dog_fashion.dm +++ b/code/datums/dog_fashion.dm @@ -31,9 +31,9 @@ if(speak_emote) D.speak_emote = speak_emote -/datum/dog_fashion/proc/get_image(var/dir) +/datum/dog_fashion/proc/get_overlay(var/dir) if(icon_file && obj_icon_state) - var/image/corgI = image(icon_file, icon_state = obj_icon_state, dir = dir) + var/image/corgI = image(icon_file, obj_icon_state, dir = dir) corgI.alpha = obj_alpha corgI.color = obj_color return corgI diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm new file mode 100644 index 0000000000..1cb3a97d9f --- /dev/null +++ b/code/datums/mutable_appearance.dm @@ -0,0 +1,18 @@ +// Mutable appearances are an inbuilt byond datastructure. Read the documentation on them by hitting F1 in DM. +// Basically use them instead of images for overlays/underlays and when changing an object's appearance if you're doing so with any regularity. +// Unless you need the overlay/underlay to have a different direction than the base object. Then you have to use an image due to a bug. + +// Mutable appearances are children of images, just so you know. + +/mutable_appearance/New() + ..() + plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE + // And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var + +// Helper similar to image() +/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER) + var/mutable_appearance/MA = new() + MA.icon = icon + MA.icon_state = icon_state + MA.layer = layer + return MA \ No newline at end of file diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index 55f2b03161..caab422e8b 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -15,7 +15,7 @@ GLOBAL_LIST_EMPTY(mutations_list) var/lowest_value = 256 * 8 var/text_gain_indication = "" var/text_lose_indication = "" - var/list/visual_indicators = list() + var/list/mutable_appearance/visual_indicators = list() var/layer_used = MUTATIONS_LAYER //which mutation layer to use var/list/species_allowed = list() //to restrict mutation to only certain species var/health_req //minimum health required to acquire the mutation @@ -161,7 +161,7 @@ GLOBAL_LIST_EMPTY(mutations_list) /datum/mutation/human/telekinesis/New() ..() - visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="telekinesishead", "layer"=-MUTATIONS_LAYER) + visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "telekinesishead", -MUTATIONS_LAYER) /datum/mutation/human/telekinesis/get_visual_indicator(mob/living/carbon/human/owner) return visual_indicators[1] @@ -180,7 +180,7 @@ GLOBAL_LIST_EMPTY(mutations_list) /datum/mutation/human/cold_resistance/New() ..() - visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="fire", "layer"=-MUTATIONS_LAYER) + visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "fire", -MUTATIONS_LAYER) /datum/mutation/human/cold_resistance/get_visual_indicator(mob/living/carbon/human/owner) return visual_indicators[1] @@ -618,7 +618,7 @@ GLOBAL_LIST_EMPTY(mutations_list) /datum/mutation/human/laser_eyes/New() ..() - visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="lasereyes", "layer"=-FRONT_MUTATIONS_LAYER) + visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "lasereyes", -FRONT_MUTATIONS_LAYER) /datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner) return visual_indicators[1] @@ -640,11 +640,11 @@ GLOBAL_LIST_EMPTY(mutations_list) var/list/mut_overlay = list() if(overlays_standing[CM.layer_used]) mut_overlay = overlays_standing[CM.layer_used] - var/image/V = CM.get_visual_indicator(src) + var/mutable_appearance/V = CM.get_visual_indicator(src) if(!mut_overlay.Find(V)) //either we lack the visual indicator or we have the wrong one remove_overlay(CM.layer_used) - for(var/image/I in CM.visual_indicators) - mut_overlay.Remove(I) + for(var/mutable_appearance/MA in CM.visual_indicators) + mut_overlay.Remove(MA) mut_overlay |= V overlays_standing[CM.layer_used] = mut_overlay apply_overlay(CM.layer_used) diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index 7a8bc7f517..46853995cb 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -179,11 +179,11 @@ remove_atom_colour(FIXED_COLOUR_PRIORITY) if(is_zombie) copy_overlays(oldguy, TRUE) - var/image/I = image('icons/mob/blob.dmi', icon_state = "blob_head") + var/mutable_appearance/blob_head_overlay = mutable_appearance('icons/mob/blob.dmi', "blob_head") if(overmind) - I.color = overmind.blob_reagent_datum.complementary_color + blob_head_overlay.color = overmind.blob_reagent_datum.complementary_color color = initial(color)//looks better. - add_overlay(I) + add_overlay(blob_head_overlay) /mob/living/simple_animal/hostile/blob/blobspore/weak name = "fragile blob spore" diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index 7ae47f4c0e..6ee0a56cee 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -33,12 +33,11 @@ /obj/structure/blob/core/update_icon() cut_overlays() color = null - var/image/I = new('icons/mob/blob.dmi', "blob") + var/mutable_appearance/blob_overlay = mutable_appearance('icons/mob/blob.dmi', "blob") if(overmind) - I.color = overmind.blob_reagent_datum.color - add_overlay(I) - var/image/C = new('icons/mob/blob.dmi', "blob_core_overlay") - add_overlay(C) + blob_overlay.color = overmind.blob_reagent_datum.color + add_overlay(blob_overlay) + add_overlay(mutable_appearance('icons/mob/blob.dmi', "blob_core_overlay")) /obj/structure/blob/core/Destroy() GLOB.blob_cores -= src diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm index d778323ac2..ba92b7e03f 100644 --- a/code/game/gamemodes/blob/blobs/node.dm +++ b/code/game/gamemodes/blob/blobs/node.dm @@ -21,12 +21,11 @@ /obj/structure/blob/node/update_icon() cut_overlays() color = null - var/image/I = new('icons/mob/blob.dmi', "blob") + var/mutable_appearance/blob_overlay = mutable_appearance('icons/mob/blob.dmi', "blob") if(overmind) - I.color = overmind.blob_reagent_datum.color - add_overlay(I) - var/image/C = new('icons/mob/blob.dmi', "blob_node_overlay") - add_overlay(C) + blob_overlay.color = overmind.blob_reagent_datum.color + add_overlay(blob_overlay) + add_overlay(mutable_appearance('icons/mob/blob.dmi', "blob_node_overlay")) /obj/structure/blob/node/Destroy() GLOB.blob_nodes -= src diff --git a/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm b/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm index 31b8801028..1203c7119a 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm @@ -42,8 +42,7 @@ icon_state = "geisbinding" mob_layer = M.layer layer = M.layer - 0.01 - var/image/GB = new('icons/effects/clockwork_effects.dmi', src, "geisbinding_top", M.layer + 0.01) - add_overlay(GB) + add_overlay(mutable_appearance('icons/effects/clockwork_effects.dmi', "geisbinding_top", M.layer + 0.01)) for(var/obj/item/I in M.held_items) M.dropItemToGround(I) for(var/i in M.get_empty_held_indexes()) diff --git a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm index ffc3d5e1a1..9b2d868730 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm @@ -25,7 +25,7 @@ START_PROCESSING(SSobj, src) send_to_playing_players("\"[text2ratvar("ONCE AGAIN MY LIGHT SHALL SHINE ACROSS THIS PATHETIC REALM")]!!\"") send_to_playing_players('sound/effects/ratvar_reveal.ogg') - var/image/alert_overlay = image('icons/effects/clockwork_effects.dmi', "ratvar_alert") + var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/clockwork_effects.dmi', "ratvar_alert") var/area/A = get_area(src) notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [A.name] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay) INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency..proc/request, null, 0) diff --git a/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm b/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm index 727f13fea4..22ea9e2ce5 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm @@ -14,8 +14,8 @@ debris = list(/obj/item/clockwork/alloy_shards/medium = 1, \ /obj/item/clockwork/alloy_shards/small = 6, \ /obj/item/clockwork/component/replicant_alloy/replication_plate = 1) - var/image/daemon_glow - var/image/component_glow + var/static/mutable_appearance/daemon_glow = mutable_appearance('icons/obj/clockwork_objects.dmi', "tinkerglow") + var/static/mutable_appearance/component_glow = mutable_appearance('icons/obj/clockwork_objects.dmi', "t_random_component") var/component_id_to_produce var/production_time = 0 //last time we produced a component var/production_cooldown = 120 @@ -119,14 +119,9 @@ . = ..() if(active) var/component_color = get_component_color(component_id_to_produce) - if(!daemon_glow) - daemon_glow = new('icons/obj/clockwork_objects.dmi', "tinkerglow") daemon_glow.color = component_color add_overlay(daemon_glow) - if(!component_glow) - component_glow = new('icons/obj/clockwork_objects.dmi', "t_[component_id_to_produce ? component_id_to_produce :"random_component"]") - else - component_glow.icon_state = "t_[component_id_to_produce ? component_id_to_produce :"random_component"]" + component_glow.icon_state = "t_[component_id_to_produce ? component_id_to_produce :"random_component"]" component_glow.color = component_color add_overlay(component_glow) production_time = world.time + production_cooldown //don't immediately produce when turned on after being off diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 8d87eeb4fc..a90aeb78bc 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -201,9 +201,9 @@ return 0 /obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands) - . = list() - if(!isinhands && current_charges) - . += image(layer = MOB_LAYER+0.01, icon = 'icons/effects/effects.dmi', icon_state = "shield-cult") + . = list() + if(!isinhands && current_charges) + . += mutable_appearance('icons/effects/effects.dmi', "shield-cult", MOB_LAYER + 0.01) /obj/item/clothing/suit/hooded/cultrobes/berserker name = "flagellant's robes" diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 2e2ff9c46b..296b248938 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -775,11 +775,11 @@ structure_check() searches for nearby cultist structures required for the invoca deltimer(density_timer) air_update_turf(1) if(density) - var/image/I = image(layer = ABOVE_MOB_LAYER, icon = 'icons/effects/effects.dmi', icon_state = "barriershimmer") - I.appearance_flags = RESET_COLOR - I.alpha = 60 - I.color = "#701414" - add_overlay(I) + var/mutable_appearance/shimmer = mutable_appearance('icons/effects/effects.dmi', "barriershimmer", ABOVE_MOB_LAYER) + shimmer.appearance_flags |= RESET_COLOR + shimmer.alpha = 60 + shimmer.color = "#701414" + add_overlay(shimmer) add_atom_colour("#FF0000", FIXED_COLOUR_PRIORITY) else cut_overlays() diff --git a/code/game/gamemodes/devil/true_devil/inventory.dm b/code/game/gamemodes/devil/true_devil/inventory.dm index c474eaf116..778c421616 100644 --- a/code/game/gamemodes/devil/true_devil/inventory.dm +++ b/code/game/gamemodes/devil/true_devil/inventory.dm @@ -5,7 +5,7 @@ return 0 /mob/living/carbon/true_devil/update_inv_hands() - //TODO LORDPIDEY: Figure out how to make the hands line up properly. the l/r_hand_image should use the down sprite when facing down, left, or right, and the up sprite when facing up. + //TODO LORDPIDEY: Figure out how to make the hands line up properly. the l/r_hand_overlay should use the down sprite when facing down, left, or right, and the up sprite when facing up. remove_overlay(DEVIL_HANDS_LAYER) var/list/hands_overlays = list() var/obj/item/l_hand = get_item_for_held_index(1) //hardcoded 2-hands only, for now. @@ -17,9 +17,9 @@ if(!r_state) r_state = r_hand.icon_state - var/image/r_hand_image = r_hand.build_worn_icon(state = r_state, default_layer = DEVIL_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) + var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(state = r_state, default_layer = DEVIL_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) - hands_overlays += r_hand_image + hands_overlays += r_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) r_hand.layer = ABOVE_HUD_LAYER @@ -33,9 +33,9 @@ if(!l_state) l_state = l_hand.icon_state - var/image/l_hand_image = l_hand.build_worn_icon(state = l_state, default_layer = DEVIL_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) + var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(state = l_state, default_layer = DEVIL_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) - hands_overlays += l_hand_image + hands_overlays += l_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) l_hand.layer = ABOVE_HUD_LAYER @@ -54,6 +54,5 @@ /mob/living/carbon/true_devil/apply_overlay(cache_index) - var/image/I = devil_overlays[cache_index] - if(I) - add_overlay(I) + if((. = devil_overlays[cache_index])) + add_overlay(.) diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 575db19f5c..1f01b38860 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -37,8 +37,8 @@ var/previous_level = "" var/obj/item/nuke_core/core = null var/deconstruction_state = NUKESTATE_INTACT - var/image/lights = null - var/image/interior = null + var/lights = "" + var/interior = "" var/obj/effect/countdown/nuclearbomb/countdown var/static/bomb_set @@ -201,30 +201,32 @@ cut_overlay(interior) switch(deconstruction_state) if(NUKESTATE_UNSCREWED) - interior = image(icon,"panel-unscrewed") + interior = "panel-unscrewed" if(NUKESTATE_PANEL_REMOVED) - interior = image(icon,"panel-removed") + interior = "panel-removed" if(NUKESTATE_WELDED) - interior = image(icon,"plate-welded") + interior = "plate-welded" if(NUKESTATE_CORE_EXPOSED) - interior = image(icon,"plate-removed") + interior = "plate-removed" if(NUKESTATE_CORE_REMOVED) - interior = image(icon,"core-removed") + interior = "core-removed" if(NUKESTATE_INTACT) - interior = null + return add_overlay(interior) /obj/machinery/nuclearbomb/proc/update_icon_lights() - cut_overlay(lights) + if(lights) + cut_overlay(lights) switch(get_nuke_state()) if(NUKE_OFF_LOCKED) - lights = null + lights = "" + return if(NUKE_OFF_UNLOCKED) - lights = image(icon,"lights-safety") + lights = "lights-safety" if(NUKE_ON_TIMING) - lights = image(icon,"lights-timing") + lights = "lights-timing" if(NUKE_ON_EXPLODING) - lights = image(icon,"lights-exploding") + lights = "lights-exploding" add_overlay(lights) /obj/machinery/nuclearbomb/process() diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm index 39bd31bdb7..753cd42a4f 100644 --- a/code/game/machinery/computer/apc_control.dm +++ b/code/game/machinery/computer/apc_control.dm @@ -96,7 +96,6 @@ return if(!usr || !usr.canUseTopic(src) || usr.incapacitated() || stat || QDELETED(src)) return - var/image/I = image(src) //For feedback message flavor if(href_list["authenticate"]) var/obj/item/weapon/card/id/ID = usr.get_active_held_item() if(!istype(ID)) @@ -117,24 +116,24 @@ authenticated = FALSE auth_id = "\[NULL\]" if(href_list["restore_logging"]) - to_chat(usr, "\icon[I] Logging functionality restored from backup data.") + to_chat(usr, "\icon[src] Logging functionality restored from backup data.") emagged = FALSE LAZYADD(logs, "-=- Logging restored to full functionality at this point -=-") if(href_list["access_apc"]) playsound(src, "terminal_type", 50, 0) var/obj/machinery/power/apc/APC = locate(href_list["access_apc"]) in GLOB.apcs_list if(!APC || APC.aidisabled || APC.panel_open || QDELETED(APC)) - to_chat(usr, "\icon[I] APC does not return interface request. Remote access may be disabled.") + to_chat(usr, "\icon[src] APC does not return interface request. Remote access may be disabled.") return if(active_apc) - to_chat(usr, "\icon[I] Disconnected from [active_apc].") + to_chat(usr, "\icon[src] Disconnected from [active_apc].") active_apc.say("Remote access canceled. Interface locked.") playsound(active_apc, 'sound/machines/BoltsDown.ogg', 25, 0) playsound(active_apc, 'sound/machines/terminal_alert.ogg', 50, 0) active_apc.locked = TRUE active_apc.update_icon() active_apc = null - to_chat(usr, "\icon[I] Connected to APC in [get_area(APC)]. Interface request sent.") + to_chat(usr, "\icon[src] Connected to APC in [get_area(APC)]. Interface request sent.") log_activity("remotely accessed APC in [get_area(APC)]") APC.interact(usr, GLOB.not_incapacitated_state) playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 0b61f19f0a..c97f487718 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -419,7 +419,7 @@ to_chat(H, "\icon[customrecepient] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)") log_pda("[usr]/([usr.ckey]) (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]") customrecepient.cut_overlays() - customrecepient.add_overlay(image('icons/obj/pda.dmi', "pda-r")) + customrecepient.add_overlay(mutable_appearance('icons/obj/pda.dmi', "pda-r")) //Sender is faking as someone who exists else src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]") @@ -432,7 +432,7 @@ to_chat(H, "\icon[customrecepient] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)") log_pda("[usr]/([usr.ckey]) (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]") customrecepient.cut_overlays() - customrecepient.add_overlay(image('icons/obj/pda.dmi', "pda-r")) + customrecepient.add_overlay(mutable_appearance('icons/obj/pda.dmi', "pda-r")) //Finally.. ResetMessage() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index c8555e47ad..a9331cd142 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -366,13 +366,13 @@ set_airlock_overlays(state) /obj/machinery/door/airlock/proc/set_airlock_overlays(state) - var/image/frame_overlay - var/image/filling_overlay - var/image/lights_overlay - var/image/panel_overlay - var/image/weld_overlay - var/image/damag_overlay - var/image/sparks_overlay + var/mutable_appearance/frame_overlay + var/mutable_appearance/filling_overlay + var/mutable_appearance/lights_overlay + var/mutable_appearance/panel_overlay + var/mutable_appearance/weld_overlay + var/mutable_appearance/damag_overlay + var/mutable_appearance/sparks_overlay switch(state) if(AIRLOCK_CLOSED) @@ -494,10 +494,8 @@ pass(A) //suppress unused warning var/list/airlock_overlays = A.airlock_overlays var/iconkey = "[icon_state][icon_file]" - if(airlock_overlays[iconkey]) - return airlock_overlays[iconkey] - airlock_overlays[iconkey] = image(icon_file, icon_state) - return airlock_overlays[iconkey] + if((!(. = airlock_overlays[iconkey]))) + . = airlock_overlays[iconkey] = mutable_appearance(icon_file, icon_state) /obj/machinery/door/airlock/do_animate(animation) switch(animation) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index b37db06ac2..d9aafa1b5a 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -184,7 +184,7 @@ if(maptext) maptext = "" cut_overlays() - add_overlay(image('icons/obj/status_display.dmi', icon_state=state)) + add_overlay(mutable_appearance('icons/obj/status_display.dmi', state)) //Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index e4e1f7e75d..e6d8469943 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -36,27 +36,27 @@ else add_overlay("beakeridle") if(beaker.reagents.total_volume) - var/image/filling = image('icons/obj/iv_drip.dmi', src, "reagent") + var/mutable_appearance/filling_overlay = mutable_appearance('icons/obj/iv_drip.dmi', "reagent") var/percent = round((beaker.reagents.total_volume / beaker.volume) * 100) switch(percent) if(0 to 9) - filling.icon_state = "reagent0" + filling_overlay.icon_state = "reagent0" if(10 to 24) - filling.icon_state = "reagent10" + filling_overlay.icon_state = "reagent10" if(25 to 49) - filling.icon_state = "reagent25" + filling_overlay.icon_state = "reagent25" if(50 to 74) - filling.icon_state = "reagent50" + filling_overlay.icon_state = "reagent50" if(75 to 79) - filling.icon_state = "reagent75" + filling_overlay.icon_state = "reagent75" if(80 to 90) - filling.icon_state = "reagent80" + filling_overlay.icon_state = "reagent80" if(91 to INFINITY) - filling.icon_state = "reagent100" + filling_overlay.icon_state = "reagent100" - filling.icon += mix_color_from_reagents(beaker.reagents.reagent_list) - add_overlay(filling) + filling_overlay.color = list("#0000", "#0000", "#0000", "#000f", mix_color_from_reagents(beaker.reagents.reagent_list)) + add_overlay(filling_overlay) /obj/machinery/iv_drip/MouseDrop(mob/living/target) if(!ishuman(usr) || !usr.canUseTopic(src,BE_CLOSE) || !isliving(target)) diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 60104fbc86..2b46183efe 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -146,7 +146,7 @@ /obj/machinery/status_display/proc/set_picture(state) picture_state = state remove_display() - add_overlay(image('icons/obj/status_display.dmi', icon_state=picture_state)) + add_overlay(picture_state) /obj/machinery/status_display/proc/update_display(line1, line2) var/new_text = {"
[line1]
[line2]
"} @@ -278,7 +278,7 @@ /obj/machinery/ai_status_display/proc/set_picture(state) picture_state = state cut_overlays() - add_overlay(image('icons/obj/status_display.dmi', icon_state=picture_state)) + add_overlay(picture_state) #undef CHARS_PER_LINE #undef FOND_SIZE diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 3de0b85820..cbb4efd6b0 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -297,7 +297,7 @@ to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.") cut_overlays() if(panel_open) - add_overlay(image(icon, "[initial(icon_state)]-panel")) + add_overlay("[initial(icon_state)]-panel") playsound(src.loc, W.usesound, 50, 1) updateUsrDialog() else diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index e2cccda880..1e36149ef9 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -186,7 +186,7 @@ var/full = contents.len ? 1 : 0 icon_state = "wm_[state_open]_[full]" if(panel_open) - add_overlay(image(icon, icon_state = "wm_panel")) + add_overlay("wm_panel") /obj/machinery/washing_machine/attackby(obj/item/weapon/W, mob/user, params) if(default_deconstruction_screwdriver(user, null, null, W)) diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm index ae1f1d83ce..acc9a2a087 100644 --- a/code/game/mecha/mecha_wreckage.dm +++ b/code/game/mecha/mecha_wreckage.dm @@ -23,7 +23,7 @@ AI.apply_damage(150, BURN) //Give the AI a bit of damage from the "shock" of being suddenly shut down AI.death() //The damage is not enough to kill the AI, but to be 'corrupted files' in need of repair. AI.forceMove(src) //Put the dead AI inside the wreckage for recovery - add_overlay(image('icons/obj/projectiles.dmi', icon_state = "green_laser")) //Overlay for the recovery beacon + add_overlay(mutable_appearance('icons/obj/projectiles.dmi', "green_laser")) //Overlay for the recovery beacon AI.controlled_mech = null AI.remote_control = null diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 28bb48fc05..aca6b7a778 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -48,9 +48,9 @@ if (hides) cut_overlays() if(hides < 3) - add_overlay(image("icon" = "mecha.dmi", "icon_state" = occupant ? "ripley-g" : "ripley-g-open")) + add_overlay(occupant ? "ripley-g" : "ripley-g-open") else - add_overlay(image("icon" = "mecha.dmi", "icon_state" = occupant ? "ripley-g-full" : "ripley-g-full-open")) + add_overlay(occupant ? "ripley-g-full" : "ripley-g-full-open") /obj/mecha/working/ripley/firefighter diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index 0d4b578653..7727b4d9e9 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -161,23 +161,15 @@ for(var/Ddir in GLOB.cardinal) if(entered_dirs & Ddir) - var/image/I - if(GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"]) - I = GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"] - else - I = image(icon,"[blood_state]1",dir = Ddir) - GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"] = I - if(I) - add_overlay(I) + var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"] + if(!bloodstep_overlay) + GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]1", dir = Ddir) + add_overlay(bloodstep_overlay) if(exited_dirs & Ddir) - var/image/I - if(GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"]) - I = GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] - else - I = image(icon,"[blood_state]2",dir = Ddir) - GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] = I - if(I) - add_overlay(I) + var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] + if(!bloodstep_overlay) + GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]2", dir = Ddir) + add_overlay(bloodstep_overlay) alpha = BLOODY_FOOTPRINT_BASE_ALPHA+bloodiness diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index fa2dee2495..8dc9bd89b2 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1,4 +1,4 @@ -GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/effects/fire.dmi', "icon_state" = "fire")) +GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire")) GLOBAL_VAR_INIT(rpg_loot_items, FALSE) // if true, everyone item when created will have its name changed to be diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 098d337123..039237c63c 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -521,7 +521,7 @@ /obj/item/weapon/storage/crayons/update_icon() cut_overlays() for(var/obj/item/toy/crayon/crayon in contents) - add_overlay(image('icons/obj/crayons.dmi',crayon.item_color)) + add_overlay(mutable_appearance('icons/obj/crayons.dmi', crayon.item_color)) /obj/item/weapon/storage/crayons/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/toy/crayon)) @@ -667,10 +667,9 @@ icon_state = is_capped ? icon_capped : icon_uncapped if(use_overlays) cut_overlays() - var/image/I = image('icons/obj/crayons.dmi', - icon_state = "[is_capped ? "spraycan_cap_colors" : "spraycan_colors"]") - I.color = paint_color - add_overlay(I) + var/mutable_appearance/spray_overlay = mutable_appearance('icons/obj/crayons.dmi', "[is_capped ? "spraycan_cap_colors" : "spraycan_colors"]") + spray_overlay.color = paint_color + add_overlay(spray_overlay) /obj/item/toy/crayon/spraycan/gang //desc = "A modified container containing suspicious paint." diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 5e49db24a4..4a64cf5c0d 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -51,7 +51,7 @@ GLOBAL_LIST_EMPTY(PDAs) var/obj/item/device/paicard/pai = null // A slot for a personal AI device - var/image/photo = null //Scanned photo + var/icon/photo //Scanned photo var/list/contained_item = list(/obj/item/weapon/pen, /obj/item/toy/crayon, /obj/item/weapon/lipstick, /obj/item/device/flashlight/pen, /obj/item/clothing/mask/cigarette) var/obj/item/inserted_item //Used for pen, crayon, and lipstick insertion or removal. Same as above. @@ -82,22 +82,24 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/device/pda/update_icon() cut_overlays() + var/mutable_appearance/overlay = new() + overlay.pixel_x = overlays_x_offset if(id) - var/image/I = image(icon_state = "id_overlay", pixel_x = overlays_x_offset) - add_overlay(I) + overlay.icon_state = "id_overlay" + add_overlay(new /mutable_appearance(overlay)) if(inserted_item) - var/image/I = image(icon_state = "insert_overlay", pixel_x = overlays_x_offset) - add_overlay(I) + overlay.icon_state = "insert_overlay" + add_overlay(new /mutable_appearance(overlay)) if(fon) - var/image/I = image(icon_state = "light_overlay", pixel_x = overlays_x_offset) - add_overlay(I) + overlay.icon_state = "light_overlay" + add_overlay(new /mutable_appearance(overlay)) if(pai) if(pai.pai) - var/image/I = image(icon_state = "pai_overlay", pixel_x = overlays_x_offset) - add_overlay(I) + overlay.icon_state = "pai_overlay" + add_overlay(new /mutable_appearance(overlay)) else - var/image/I = image(icon_state = "pai_off_overlay", pixel_x = overlays_x_offset) - add_overlay(I) + overlay.icon_state = "pai_off_overlay" + add_overlay(new /mutable_appearance(overlay)) /obj/item/device/pda/MouseDrop(obj/over_object, src_location, over_location) var/mob/M = usr @@ -633,7 +635,7 @@ GLOBAL_LIST_EMPTY(PDAs) to_chat(L, "\icon[src] Message from [source.owner] ([source.ownjob]), \"[msg.message]\"[msg.get_photo_ref()] (Reply)") update_icon() - add_overlay(image(icon, icon_alert)) + add_overlay(icon_alert) /obj/item/device/pda/proc/show_to_ghosts(mob/living/user, datum/data_pda_msg/msg,multiple = 0) for(var/mob/M in GLOB.player_list) diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index d7cf9b0b9b..4f0d61c1b7 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -23,6 +23,7 @@ update_icon() //Whatever happened, update the card's state (icon, name) to match. /obj/item/device/aicard/update_icon() + cut_overlays() if(AI) name = "[initial(name)]- [AI.name]" if(AI.stat == DEAD) @@ -30,12 +31,11 @@ else icon_state = "aicard-full" if(!AI.control_disabled) - add_overlay(image('icons/obj/aicards.dmi', "aicard-on")) + add_overlay("aicard-on") AI.cancel_camera() else name = initial(name) icon_state = initial(icon_state) - cut_overlays() /obj/item/device/aicard/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index fa54e7787b..496702aa4d 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -344,8 +344,9 @@ cut_overlays() set_light(0) else if(on) - var/image/I = image(icon,"glowstick-glow",color) - add_overlay(I) + var/mutable_appearance/glowstick_overlay = mutable_appearance(icon, "glowstick-glow") + glowstick_overlay.color = color + add_overlay(glowstick_overlay) item_state = "glowstick-on" set_light(brightness_on) else diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index c8c7cd1397..f38cad82f2 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -493,7 +493,7 @@ /obj/item/projectile/bullet/reusable/lollipop/New() var/obj/item/weapon/reagent_containers/food/snacks/lollipop/S = new ammo_type(src) color2 = S.headcolor - var/image/head = image(icon = 'icons/obj/projectiles.dmi', icon_state = "lollipop_2") + var/mutable_appearance/head = mutable_appearance('icons/obj/projectiles.dmi', "lollipop_2") head.color = color2 add_overlay(head) diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index f1271b3cb9..3a7a92f701 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -73,18 +73,18 @@ if(hp <= 0) visible_message("[src] breaks into tiny pieces and collapses!") qdel(src) - var/image/I = image("icon"='icons/effects/effects.dmi', "icon_state"="scorch", "layer"=OBJ_LAYER+0.5) - I.pixel_x = p_x - 1 //offset correction - I.pixel_y = p_y - 1 + var/image/bullet_hole = image('icons/effects/effects.dmi', "scorch", OBJ_LAYER + 0.5) + bullet_hole.pixel_x = p_x - 1 //offset correction + bullet_hole.pixel_y = p_y - 1 if(decaltype == DECALTYPE_SCORCH) - I.setDir(pick(NORTH,SOUTH,EAST,WEST))// random scorch design + bullet_hole.setDir(pick(NORTH,SOUTH,EAST,WEST))// random scorch design if(P.damage >= 20 || istype(P, /obj/item/projectile/beam/practice)) - I.setDir(pick(NORTH,SOUTH,EAST,WEST)) + bullet_hole.setDir(pick(NORTH,SOUTH,EAST,WEST)) else - I.icon_state = "light_scorch" + bullet_hole.icon_state = "light_scorch" else - I.icon_state = "dent" - add_overlay(I) + bullet_hole.icon_state = "dent" + add_overlay(bullet_hole) return return -1 diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm index 5613891326..e32d365298 100644 --- a/code/game/objects/items/weapons/chrono_eraser.dm +++ b/code/game/objects/items/weapons/chrono_eraser.dm @@ -155,7 +155,7 @@ var/mob/living/captured = null var/obj/item/weapon/gun/energy/chrono_gun/gun = null var/tickstokill = 15 - var/image/mob_underlay = null + var/mutable_appearance/mob_underlay var/preloaded = 0 var/RPpos = null @@ -172,7 +172,7 @@ mob_icon.Blend(removing_frame, ICON_MULTIPLY) cached_icon.Insert(mob_icon, "frame[i]") - mob_underlay = new(cached_icon, "frame1") + mob_underlay = mutable_appearance(cached_icon, "frame1") update_icon() desc = initial(desc) + "
It appears to contain [target.name]." diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index d7ba81590e..3cf5305dcb 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -496,11 +496,11 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/weapon/lighter/greyscale/update_icon() cut_overlays() - var/image/I = image(icon,"[initial(icon_state)]_base") - I.appearance_flags = RESET_COLOR //the edging doesn't change color + var/mutable_appearance/base_overlay = mutable_appearance(icon,"[initial(icon_state)]_base") + base_overlay.appearance_flags = RESET_COLOR //the edging doesn't change color if(lit) - I.icon_state = "[initial(icon_state)]_on" - add_overlay(I) + base_overlay.icon_state = "[initial(icon_state)]_on" + add_overlay(base_overlay) /obj/item/weapon/lighter/greyscale/ignition_effect(atom/A, mob/user) . = "After some fiddling, [user] manages to light [A] with [src]." @@ -651,9 +651,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM screw = 1 to_chat(user, "You open the cap on the [src]") if(super) - add_overlay(image(icon, "vapeopen_med")) + add_overlay("vapeopen_med") else - add_overlay(image(icon, "vapeopen_low")) + add_overlay("vapeopen_low") else screw = 0 to_chat(user, "You close the cap on the [src]") @@ -665,12 +665,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM cut_overlays() super = 1 to_chat(user, "You increase the voltage in the [src]") - add_overlay(image(icon, "vapeopen_med")) + add_overlay("vapeopen_med") else cut_overlays() super = 0 to_chat(user, "You decrease the voltage in the [src]") - add_overlay(image(icon, "vapeopen_low")) + add_overlay("vapeopen_low") if(screw && emagged) to_chat(user, "The [name] can't be modified!") @@ -683,7 +683,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM emagged = 1 super = 0 to_chat(user, "You maximize the voltage in the [src]") - add_overlay(image(icon, "vapeopen_high")) + add_overlay("vapeopen_high") var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread //for effect sp.set_up(5, 1, src) sp.start() diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 785839ba2d..9d0ad5ab78 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -38,10 +38,10 @@ to_chat(user, "You twist \the [src] [open ? "closed" : "open"].") open = !open if(open) - var/image/colored = image("icon"='icons/obj/items.dmi', "icon_state"="lipstick_uncap_color") - colored.color = colour + var/mutable_appearance/colored_overlay = mutable_appearance(icon, "lipstick_uncap_color") + colored_overlay.color = colour icon_state = "lipstick_uncap" - add_overlay(colored) + add_overlay(colored_overlay) else icon_state = "lipstick" diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 5c637ba31c..756512dff1 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -16,7 +16,7 @@ /obj/item/weapon/c4/New() wires = new /datum/wires/explosive/c4(src) - image_overlay = image('icons/obj/grenade.dmi', "plastic-explosive2") + plastic_overlay = mutable_appearance(icon, "plastic-explosive2") ..() /obj/item/weapon/c4/Destroy() @@ -92,7 +92,7 @@ message_admins(message,0,1) log_game("[key_name(user)] planted [name] on [target.name] at [COORD(target)] with [timer] second fuse") - target.add_overlay(image_overlay, 1) + target.add_overlay(plastic_overlay, 1) to_chat(user, "You plant the bomb. Timer counting down from [timer].") addtimer(CALLBACK(src, .proc/explode), timer * 10) @@ -103,7 +103,7 @@ if(target) if(!QDELETED(target)) location = get_turf(target) - target.cut_overlay(image_overlay, TRUE) + target.cut_overlay(plastic_overlay, TRUE) else location = get_turf(src) if(location) diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm index 4c3e80ff6d..f4d573e3ba 100644 --- a/code/game/objects/items/weapons/grenades/ghettobomb.dm +++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm @@ -19,8 +19,8 @@ /obj/item/weapon/grenade/iedcasing/New(loc) ..() - add_overlay(image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")) - add_overlay(image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_wired")) + add_overlay("improvised_grenade_filled") + add_overlay("improvised_grenade_wired") times = list("5" = 10, "-1" = 20, "[rand(30,80)]" = 50, "[rand(65,180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value] det_time = text2num(pickweight(times)) if(det_time < 0) //checking for 'duds' @@ -33,13 +33,10 @@ ..() var/obj/item/weapon/reagent_containers/food/drinks/soda_cans/can = locate() in contents if(can) - var/muh_layer = can.layer - var/muh_plane = can.plane - can.layer = FLOAT_LAYER - can.plane = FLOAT_PLANE - underlays += can - can.layer = muh_layer - can.plane = muh_plane + var/mutable_appearance/can_underlay = new(can) + can_underlay.layer = FLOAT_LAYER + can_underlay.plane = FLOAT_PLANE + underlays += can_underlay /obj/item/weapon/grenade/iedcasing/attack_self(mob/user) // @@ -47,7 +44,7 @@ if(clown_check(user)) to_chat(user, "You light the [name]!") active = 1 - cut_overlay(image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled"), TRUE) //this line make no sense + cut_overlay("improvised_grenade_filled") icon_state = initial(icon_state) + "_active" add_fingerprint(user) var/turf/bombturf = get_turf(src) diff --git a/code/game/objects/items/weapons/grenades/plastic.dm b/code/game/objects/items/weapons/grenades/plastic.dm index 477a50330e..aedf0954c2 100644 --- a/code/game/objects/items/weapons/grenades/plastic.dm +++ b/code/game/objects/items/weapons/grenades/plastic.dm @@ -7,7 +7,7 @@ det_time = 10 display_timer = 0 var/atom/target = null - var/image_overlay = null + var/mutable_appearance/plastic_overlay var/obj/item/device/assembly_holder/nadeassembly = null var/assemblyattacher var/directional = FALSE @@ -15,7 +15,7 @@ var/boom_sizes = list(0, 0, 3) /obj/item/weapon/grenade/plastic/New() - image_overlay = image('icons/obj/grenade.dmi', "[item_state]2") + plastic_overlay = mutable_appearance(icon, "[item_state]2") ..() /obj/item/weapon/grenade/plastic/Destroy() @@ -50,7 +50,7 @@ if(target) if(!QDELETED(target)) location = get_turf(target) - target.cut_overlay(image_overlay, TRUE) + target.cut_overlay(plastic_overlay, TRUE) else location = get_turf(src) if(location) @@ -111,7 +111,7 @@ message_admins("[ADMIN_LOOKUPFLW(user)] planted [name] on [target.name] at [ADMIN_COORDJMP(target)] with [det_time] second fuse",0,1) log_game("[key_name(user)] planted [name] on [target.name] at [COORD(src)] with [det_time] second fuse") - target.add_overlay(image_overlay, 1) + target.add_overlay(plastic_overlay, 1) if(!nadeassembly) to_chat(user, "You plant the bomb. Timer counting down from [det_time].") addtimer(CALLBACK(src, .proc/prime), det_time*10) diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm index d42e135aeb..571aece4c3 100644 --- a/code/game/objects/items/weapons/holy_weapons.dm +++ b/code/game/objects/items/weapons/holy_weapons.dm @@ -71,7 +71,7 @@ /obj/item/weapon/nullrod/staff/worn_overlays(isinhands) . = list() if(isinhands) - . += image(layer = MOB_LAYER+0.01, icon = 'icons/effects/effects.dmi', icon_state = "[shield_icon]") + . += mutable_appearance('icons/effects/effects.dmi', shield_icon, MOB_LAYER + 0.01) /obj/item/weapon/nullrod/staff/blue name = "blue holy staff" diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm index c053b6ed47..61e68934b9 100644 --- a/code/game/objects/items/weapons/pneumaticCannon.dm +++ b/code/game/objects/items/weapons/pneumaticCannon.dm @@ -162,5 +162,5 @@ src.cut_overlays() if(!tank) return - src.add_overlay(image('icons/obj/pneumaticCannon.dmi', "[tank.icon_state]")) + add_overlay(tank.icon_state) src.update_icon() diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 9806dee20d..9b96571d6f 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -334,14 +334,14 @@ /obj/item/weapon/storage/bag/tray/proc/rebuild_overlays() cut_overlays() for(var/obj/item/I in contents) - add_overlay(image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1)) + add_overlay(mutable_appearance(I.icon, I.icon_state)) /obj/item/weapon/storage/bag/tray/remove_from_storage(obj/item/W as obj, atom/new_location) ..() rebuild_overlays() /obj/item/weapon/storage/bag/tray/handle_item_insertion(obj/item/I, prevent_warning = 0) - add_overlay(image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1)) + add_overlay(mutable_appearance(I.icon, I.icon_state)) . = ..() diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 9410b29ea0..646768cea8 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -38,7 +38,7 @@ . = ..() if(illustration) cut_overlays() - add_overlay(image('icons/obj/storage.dmi', "[illustration]")) + add_overlay(illustration) /obj/item/weapon/storage/box/attack_self(mob/user) ..() diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 3923bf9da9..0c63fa6dd8 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -141,12 +141,15 @@ add_overlay("[icon_state]_open") var/i = contents.len for(var/C in contents) + var/mutable_appearance/inserted_overlay = mutable_appearance(icon) + inserted_overlay.pixel_x = 1 * (i - 1) if(istype(C, /obj/item/weapon/lighter/greyscale)) - add_overlay(image(icon = src.icon, icon_state = "lighter_in", pixel_x = 1 * (i -1))) + inserted_overlay.icon_state = "lighter_in" else if(istype(C, /obj/item/weapon/lighter)) - add_overlay(image(icon = src.icon, icon_state = "zippo_in", pixel_x = 1 * (i -1))) + inserted_overlay.icon_state = "zippo_in" else - add_overlay(image(icon = src.icon, icon_state = "cigarette", pixel_x = 1 * (i -1))) + inserted_overlay.icon_state = "cigarette" + add_overlay(inserted_overlay) i-- else cut_overlays() @@ -247,13 +250,14 @@ spawn_type = /obj/item/clothing/mask/cigarette/cigar /obj/item/weapon/storage/fancy/cigarettes/cigars/update_icon() + cut_overlays() if(fancy_open) - cut_overlays() add_overlay("[icon_state]_open") + var/mutable_appearance/cigar_overlay = mutable_appearance(icon, icon_type) for(var/c = contents.len, c >= 1, c--) - add_overlay(image(icon = src.icon, icon_state = icon_type, pixel_x = 4 * (c -1))) + cigar_overlay.pixel_x = 4 * (c - 1) + add_overlay(cigar_overlay) else - cut_overlays() icon_state = "cigarcase" /obj/item/weapon/storage/fancy/cigarettes/cigars/cohiba diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index b628832aa7..f48a7150a7 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -94,7 +94,7 @@ else if ((src.code == src.l_code) && (src.l_set == 1)) src.locked = 0 cut_overlays() - add_overlay(image('icons/obj/storage.dmi', icon_opened)) + add_overlay(icon_opened) src.code = null else src.code = "ERROR" diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index b72a197791..9740aa22a8 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -29,7 +29,7 @@ ..() cut_overlays() if(has_latches) - add_overlay(image('icons/obj/storage.dmi', "[latches]")) + add_overlay(latches) /obj/item/weapon/storage/toolbox/suicide_act(mob/user) diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm index ecca6aabfc..265e6bb2e5 100644 --- a/code/game/objects/items/weapons/tanks/watertank.dm +++ b/code/game/objects/items/weapons/tanks/watertank.dm @@ -370,7 +370,7 @@ cut_overlays() if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi',icon_state = "backpack-10") + var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "backpack-10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) @@ -388,7 +388,7 @@ . = list() //inhands + reagent_filling if(!isinhands && reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi',icon_state = "backpackmob-10") + var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "backpackmob-10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 45f082f72c..702e72842f 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -148,7 +148,7 @@ ///// ACID -GLOBAL_DATUM_INIT(acid_overlay, /image, image("icon" = 'icons/effects/effects.dmi', "icon_state" = "acid")) +GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', "acid")) //the obj's reaction when touched by acid /obj/acid_act(acidpwr, acid_volume) diff --git a/code/game/objects/structures/beds_chairs/alien_nest.dm b/code/game/objects/structures/beds_chairs/alien_nest.dm index f79e06e92d..ce3d0882ce 100644 --- a/code/game/objects/structures/beds_chairs/alien_nest.dm +++ b/code/game/objects/structures/beds_chairs/alien_nest.dm @@ -12,11 +12,7 @@ canSmoothWith = null buildstacktype = null flags = NODECONSTRUCT - var/image/nest_overlay - -/obj/structure/bed/nest/New() - nest_overlay = image('icons/mob/alien.dmi', "nestoverlay", layer=LYING_MOB_LAYER) - return ..() + var/static/mutable_appearance/nest_overlay = mutable_appearance('icons/mob/alien.dmi', "nestoverlay", LYING_MOB_LAYER) /obj/structure/bed/nest/user_unbuckle_mob(mob/living/buckled_mob, mob/living/user) if(has_buckled_mobs()) diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index fdded787bd..87560f426f 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -145,11 +145,11 @@ obj_integrity = 70 max_integrity = 70 buildstackamount = 2 - var/image/armrest = null + var/mutable_appearance/armrest item_chair = null /obj/structure/chair/comfy/Initialize() - armrest = image("icons/obj/chairs.dmi", "comfychair_armrest") + armrest = mutable_appearance('icons/obj/chairs.dmi', "comfychair_armrest") armrest.layer = ABOVE_MOB_LAYER return ..() diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index 0183d3605f..aa590cfb29 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -8,7 +8,7 @@ /obj/structure/chair/e_chair/New() ..() - add_overlay(image('icons/obj/chairs.dmi', src, "echair_over", MOB_LAYER + 1)) + add_overlay(mutable_appearance('icons/obj/chairs.dmi', "echair_over", MOB_LAYER + 1)) /obj/structure/chair/e_chair/attackby(obj/item/weapon/W, mob/user, params) if(istype(W, /obj/item/weapon/wrench)) diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm index 077e405616..be8c336c06 100644 --- a/code/game/objects/structures/guncase.dm +++ b/code/game/objects/structures/guncase.dm @@ -7,7 +7,7 @@ anchored = 0 density = 1 opacity = 0 - var/case_type = null + var/case_type = "" var/gun_category = /obj/item/weapon/gun var/open = 1 var/capacity = 4 @@ -25,8 +25,10 @@ /obj/structure/guncase/update_icon() cut_overlays() if(case_type && LAZYLEN(contents)) + var/mutable_appearance/gun_overlay = mutable_appearance(icon, case_type) for(var/i in 1 to contents.len) - add_overlay(image(icon = src.icon, icon_state = "[case_type]", pixel_x = 3 * (i - 1) )) + gun_overlay.pixel_x = 3 * (i - 1) + add_overlay(gun_overlay) if(open) add_overlay("[icon_state]_open") else diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm index eae2041a31..730b9e057c 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube.dm @@ -143,21 +143,21 @@ /obj/structure/transit_tube/proc/create_tube_overlay(direction, shift_dir) - var/image/I + var/image/tube_overlay = new(dir = direction) if(shift_dir) - I = image(loc = src, icon_state = "decorative_diag", dir = direction) + tube_overlay.icon_state = "decorative_diag" switch(shift_dir) if(NORTH) - I.pixel_y = 32 + tube_overlay.pixel_y = 32 if(SOUTH) - I.pixel_y = -32 + tube_overlay.pixel_y = -32 if(EAST) - I.pixel_x = 32 + tube_overlay.pixel_x = 32 if(WEST) - I.pixel_x = -32 + tube_overlay.pixel_x = -32 else - I = image(loc = src, icon_state = "decorative", dir = direction) - add_overlay(I) + tube_overlay.icon_state = "decorative" + add_overlay(tube_overlay) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 56a8d0410c..3db570db83 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -239,7 +239,7 @@ qdel(mymist) if(on) - add_overlay(image('icons/obj/watercloset.dmi', src, "water", MOB_LAYER + 1, dir)) + add_overlay(mutable_appearance('icons/obj/watercloset.dmi', "water", MOB_LAYER + 1)) if(watertemp == "freezing") return if(!ismist) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index ac1748c694..0b2563a7b0 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -18,7 +18,7 @@ var/fulltile = 0 var/glass_type = /obj/item/stack/sheet/glass var/glass_amount = 1 - var/image/crack_overlay + var/static/mutable_appearance/crack_overlay = mutable_appearance('icons/obj/structures.dmi') var/list/debris = list() can_be_unanchored = 1 resistance_flags = ACID_PROOF @@ -377,10 +377,10 @@ if(smooth) queue_smooth(src) - cut_overlay(crack_overlay) + cut_overlays() if(ratio > 75) return - crack_overlay = image('icons/obj/structures.dmi',"damage[ratio]",-(layer+0.1)) + crack_overlay.icon_state = "damage[ratio]" add_overlay(crack_overlay) /obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm index f8cb0d1be3..741d4f2958 100644 --- a/code/game/turfs/closed.dm +++ b/code/game/turfs/closed.dm @@ -71,10 +71,8 @@ /turf/closed/indestructible/fakeglass/Initialize() ..() icon_state = null //set the icon state to null, so our base state isn't visible - var/image/I = image('icons/obj/structures.dmi', loc = src, icon_state = "grille") - underlays += I //add a grille underlay - I = image('icons/turf/floors.dmi', loc = src, icon_state = "plating") - underlays += I //add the plating underlay, below the grille + underlays += mutable_appearance('icons/obj/structures.dmi', "grille") //add a grille underlay + underlays += mutable_appearance('icons/turf/floors.dmi', "plating") //add the plating underlay, below the grille /turf/closed/indestructible/fakedoor name = "Centcom Access" diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index ee5527c0f5..7183d33ef9 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -3,7 +3,7 @@ var/wet = 0 var/wet_time = 0 // Time in seconds that this floor will be wet for. - var/image/wet_overlay = null + var/mutable_appearance/wet_overlay /turf/open/indestructible name = "floor" @@ -183,17 +183,22 @@ if(wet_setting != TURF_DRY) if(wet_overlay) cut_overlay(wet_overlay) - wet_overlay = null + else + wet_overlay = mutable_appearance() var/turf/open/floor/F = src if(istype(F)) if(wet_setting == TURF_WET_PERMAFROST) - wet_overlay = image('icons/effects/water.dmi', src, "ice_floor") + wet_overlay.icon = 'icons/effects/water.dmi' + wet_overlay.icon_state = "ice_floor" else if(wet_setting == TURF_WET_ICE) - wet_overlay = image('icons/turf/overlays.dmi', src, "snowfloor") + wet_overlay.icon = 'icons/turf/overlays.dmi' + wet_overlay.icon_state = "snowfloor" else - wet_overlay = image('icons/effects/water.dmi', src, "wet_floor_static") + wet_overlay.icon = 'icons/effects/water.dmi' + wet_overlay.icon_state = "wet_floor_static" else - wet_overlay = image('icons/effects/water.dmi', src, "wet_static") + wet_overlay.icon = 'icons/effects/water.dmi' + wet_overlay.icon_state = "wet_static" add_overlay(wet_overlay) HandleWet() diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index d418c0a48a..5805d75e56 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -21,7 +21,7 @@ var/spread = 0 //will the seam spread? var/spreadChance = 0 //the percentual chance of an ore spreading to the neighbouring tiles var/last_act = 0 - var/scan_state = null //Holder for the image we display when we're pinged by a mining scanner + var/scan_state = "" //Holder for the image we display when we're pinged by a mining scanner var/defer_change = 0 /turf/closed/mineral/Initialize() @@ -380,7 +380,7 @@ var/stage = 0 //How far into the lifecycle of gibtonite we are, 0 is untouched, 1 is active and attempting to detonate, 2 is benign and ready for extraction var/activated_ckey = null //These are to track who triggered the gibtonite deposit for logging purposes var/activated_name = null - var/activated_image = null + var/mutable_appearance/activated_overlay /turf/closed/mineral/gibtonite/Initialize() det_time = rand(8,10) //So you don't know exactly when the hot potato will explode @@ -394,9 +394,8 @@ /turf/closed/mineral/gibtonite/proc/explosive_reaction(mob/user = null, triggered_by_explosion = 0) if(stage == 0) - var/image/I = image('icons/turf/smoothrocks.dmi', loc = src, icon_state = "rock_Gibtonite_active", layer = ON_EDGED_TURF_LAYER) - add_overlay(I) - activated_image = I + activated_overlay = mutable_appearance('icons/turf/smoothrocks.dmi', "rock_Gibtonite_active", ON_EDGED_TURF_LAYER) + add_overlay(activated_overlay) name = "gibtonite deposit" desc = "An active gibtonite reserve. Run!" stage = 1 @@ -433,9 +432,9 @@ /turf/closed/mineral/gibtonite/proc/defuse() if(stage == 1) - cut_overlay(activated_image) - var/image/I = image('icons/turf/smoothrocks.dmi', loc = src, icon_state = "rock_Gibtonite_inactive", layer = ON_EDGED_TURF_LAYER) - add_overlay(I) + cut_overlay(activated_overlay) + activated_overlay.icon_state = "rock_Gibtonite_inactive" + add_overlay(activated_overlay) desc = "An inactive gibtonite reserve. The ore can be extracted." stage = 2 if(det_time < 0) diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 70d70c899a..39f31183a2 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -17,18 +17,18 @@ if(src.client.handle_spam_prevention(msg,MUTE_PRAY)) return - var/image/cross = image('icons/obj/storage.dmi',"bible") + var/mutable_appearance/cross = mutable_appearance('icons/obj/storage.dmi', "bible") var/font_color = "purple" var/prayer_type = "PRAYER" var/deity if(usr.job == "Chaplain") - cross = image('icons/obj/storage.dmi',"kingyellow") + cross.icon_state = "kingyellow" font_color = "blue" prayer_type = "CHAPLAIN PRAYER" if(SSreligion.deity) deity = SSreligion.deity else if(iscultist(usr)) - cross = image('icons/obj/storage.dmi',"tome") + cross.icon_state = "tome" font_color = "red" prayer_type = "CULTIST PRAYER" deity = "Nar-Sie" diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 8b1e92743d..0b6f2db5b7 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -44,14 +44,11 @@ add_overlay("[O]_l") if(a_right) - var/list/images = list() - images += image(icon, icon_state = "[a_right.icon_state]_left") + var/mutable_appearance/right = mutable_appearance(icon, "[a_right.icon_state]_left") + right.transform = matrix(-1, 0, 0, 0, 1, 0) for(var/O in a_right.attached_overlays) - images += image(icon, icon_state = "[O]_l") - var/matrix = matrix(-1, 0, 0, 0, 1, 0) - for(var/image/I in images) - I.transform = matrix - add_overlay(I) + right.add_overlay("[O]_l") + add_overlay(right) if(master) master.update_icon() diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index a838f53da7..cfe3719423 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -201,17 +201,10 @@ Pipelines + Other Objects -> Pipe network //Generate a unique identifier for this image combination var/identifier = iconsetids[iconset] + "_[iconstate]_[direction]_[col]" - var/image/img - if(pipeimages[identifier] == null) - img = image(iconset, icon_state=iconstate, dir=direction) - img.color = col - - pipeimages[identifier] = img - - else - img = pipeimages[identifier] - - return img + if((!(. = pipeimages[identifier]))) + var/image/pipe_overlay + pipe_overlay = . = pipeimages[identifier] = image(iconset, iconstate, dir = direction) + pipe_overlay.color = col /obj/machinery/atmospherics/on_construction(pipe_type, obj_color) if(can_unwrench) diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm index 8b55ce14fc..d12204d8ad 100644 --- a/code/modules/atmospherics/machinery/other/miner.dm +++ b/code/modules/atmospherics/machinery/other/miner.dm @@ -98,12 +98,11 @@ /obj/machinery/atmospherics/miner/update_icon() overlays.Cut() if(broken) - var/image/A = image(icon, "broken") - add_overlay(A) + add_overlay("broken") else if(active) - var/image/A = image(icon, "on") - A.color = overlay_color - add_overlay(A) + var/mutable_appearance/on_overlay = mutable_appearance(icon, "on") + on_overlay.color = overlay_color + add_overlay(on_overlay) /obj/machinery/atmospherics/miner/process() update_power() diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 81eea35aba..3b5b93ce6f 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -250,9 +250,9 @@ BLIND // can't see anything . = list() if(!isinhands) if(damaged_clothes) - . += image("icon"='icons/effects/item_damage.dmi', "icon_state"="damagedgloves") + . += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves") if(blood_DNA) - . += image("icon"='icons/effects/blood.dmi', "icon_state"="bloodyhands") + . += mutable_appearance('icons/effects/blood.dmi', "bloodyhands") /obj/item/clothing/gloves/update_clothes_damaged_state(damaging = TRUE) ..() @@ -278,9 +278,9 @@ BLIND // can't see anything . = list() if(!isinhands) if(damaged_clothes) - . += image("icon"='icons/effects/item_damage.dmi', "icon_state"="damagedhelmet") + . += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet") if(blood_DNA) - . += image("icon"='icons/effects/blood.dmi', "icon_state"="helmetblood") + . += mutable_appearance('icons/effects/blood.dmi', "helmetblood") /obj/item/clothing/head/update_clothes_damaged_state(damaging = TRUE) ..() @@ -303,9 +303,9 @@ BLIND // can't see anything if(!isinhands) if(body_parts_covered & HEAD) if(damaged_clothes) - . += image("icon"='icons/effects/item_damage.dmi', "icon_state"="damagedmask") + . += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask") if(blood_DNA) - . += image("icon"='icons/effects/blood.dmi', "icon_state"="maskblood") + . += mutable_appearance('icons/effects/blood.dmi', "maskblood") //Mask @@ -325,9 +325,9 @@ BLIND // can't see anything if(!isinhands) if(body_parts_covered & HEAD) if(damaged_clothes) - . += image("icon"='icons/effects/item_damage.dmi', "icon_state"="damagedmask") + . += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask") if(blood_DNA) - . += image("icon"='icons/effects/blood.dmi', "icon_state"="maskblood") + . += mutable_appearance('icons/effects/blood.dmi', "maskblood") /obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE) ..() @@ -399,9 +399,9 @@ BLIND // can't see anything bloody = bloody_shoes[BLOOD_STATE_HUMAN] if(damaged_clothes) - . += image("icon"='icons/effects/item_damage.dmi', "icon_state"="damagedshoe") + . += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe") if(bloody) - . += image("icon"='icons/effects/blood.dmi', "icon_state"="shoeblood") + . += mutable_appearance('icons/effects/blood.dmi', "shoeblood") /obj/item/clothing/shoes/equipped(mob/user, slot) . = ..() @@ -454,9 +454,9 @@ BLIND // can't see anything . = list() if(!isinhands) if(damaged_clothes) - . += image("icon"='icons/effects/item_damage.dmi', "icon_state"="damaged[blood_overlay_type]") + . += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]") if(blood_DNA) - . += image("icon"='icons/effects/blood.dmi', "icon_state"="[blood_overlay_type]blood") + . += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood") /obj/item/clothing/suit/update_clothes_damaged_state(damaging = TRUE) ..() @@ -533,17 +533,17 @@ BLIND // can't see anything if(!isinhands) if(damaged_clothes) - . += image("icon"='icons/effects/item_damage.dmi', "icon_state"="damageduniform") + . += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform") if(blood_DNA) - . += image("icon"='icons/effects/blood.dmi', "icon_state"="uniformblood") + . += mutable_appearance('icons/effects/blood.dmi', "uniformblood") if(hastie) var/tie_color = hastie.item_color if(!tie_color) tie_color = hastie.icon_state - var/image/tI = image("icon"='icons/mob/ties.dmi', "icon_state"="[tie_color]") - tI.alpha = hastie.alpha - tI.color = hastie.color - . += tI + var/mutable_appearance/tie = mutable_appearance('icons/mob/ties.dmi', "[tie_color]") + tie.alpha = hastie.alpha + tie.color = hastie.color + . += tie /obj/item/clothing/under/update_clothes_damaged_state(damaging = TRUE) ..() diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index 15e4d3f885..10924c233a 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -30,7 +30,6 @@ var/list/hands_nodrop = list() var/obj/item/clothing/head/helmet/space/chronos/helmet = null var/obj/effect/chronos_cam/camera = null - var/image/phase_underlay = null var/datum/action/innate/chrono_teleport/teleport_now = new var/activating = 0 var/activated = 0 @@ -97,10 +96,6 @@ for(var/obj/item/I in user.held_items) if(I in hands_nodrop) I.flags &= ~NODROP - if(phase_underlay && !QDELETED(phase_underlay)) - user.underlays -= phase_underlay - qdel(phase_underlay) - phase_underlay = null if(camera) camera.remove_target_ui() camera.loc = user @@ -133,8 +128,6 @@ user.ExtinguishMob() - phase_underlay = create_phase_underlay(user) - hands_nodrop = list() for(var/obj/item/I in user.held_items) if(!(I.flags & NODROP)) @@ -171,15 +164,6 @@ else finish_chronowalk(user, to_turf) - -/obj/item/clothing/suit/space/chronos/proc/create_phase_underlay(var/mob/user) - var/icon/user_icon = icon('icons/effects/alphacolors.dmi', "") - user_icon.AddAlphaMask(getFlatIcon(user)) - var/image/phase = new(user_icon) - phase.appearance_flags = RESET_COLOR|RESET_ALPHA - user.underlays += phase - return phase - /obj/item/clothing/suit/space/chronos/process() if(activated) var/mob/living/carbon/human/user = src.loc diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index d8a0c97f51..0c3d20892f 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -597,9 +597,9 @@ C.update_inv_wear_suit() /obj/item/clothing/suit/space/hardsuit/shielded/worn_overlays(isinhands) - . = list() - if(!isinhands) - . += image(layer = MOB_LAYER+0.01, icon = 'icons/effects/effects.dmi', icon_state = "[shield_state]") + . = list() + if(!isinhands) + . += mutable_appearance('icons/effects/effects.dmi', shield_state, MOB_LAYER + 0.01) /obj/item/clothing/head/helmet/space/hardsuit/shielded resistance_flags = FIRE_PROOF | ACID_PROOF diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 8772f20212..66339b8c86 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -1,546 +1,545 @@ -/* - * Contains: - * Lasertag - * Costume - * Misc - */ - -/* - * Lasertag - */ -/obj/item/clothing/suit/bluetag - name = "blue laser tag armor" - desc = "A piece of plastic armor. It has sensors that react to red light." //Lasers are concentrated light - icon_state = "bluetag" - item_state = "bluetag" - blood_overlay_type = "armor" - body_parts_covered = CHEST - allowed = list (/obj/item/weapon/gun/energy/laser/bluetag) - resistance_flags = 0 - -/obj/item/clothing/suit/redtag - name = "red laser tag armor" - desc = "A piece of plastic armor. It has sensors that react to blue light." - icon_state = "redtag" - item_state = "redtag" - blood_overlay_type = "armor" - body_parts_covered = CHEST - allowed = list (/obj/item/weapon/gun/energy/laser/redtag) - resistance_flags = 0 - -/* - * Costume - */ -/obj/item/clothing/suit/pirate - name = "pirate coat" - desc = "Yarr." - icon_state = "pirate" - item_state = "pirate" - allowed = list(/obj/item/weapon/melee/energy/sword/pirate, /obj/item/clothing/glasses/eyepatch, /obj/item/weapon/reagent_containers/food/drinks/bottle/rum) - -/obj/item/clothing/suit/pirate/captain - name = "pirate captain coat" - desc = "Yarr." - icon_state = "hgpirate" - item_state = "hgpirate" - - -/obj/item/clothing/suit/cyborg_suit - name = "cyborg suit" - desc = "Suit for a cyborg costume." - icon_state = "death" - item_state = "death" - flags = CONDUCT - fire_resist = T0C+5200 - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - - -/obj/item/clothing/suit/justice - name = "justice suit" - desc = "this pretty much looks ridiculous" //Needs no fixing - icon_state = "justice" - item_state = "justice" - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - - -/obj/item/clothing/suit/judgerobe - name = "judge's robe" - desc = "This robe commands authority." - icon_state = "judge" - item_state = "judge" - body_parts_covered = CHEST|GROIN|LEGS|ARMS - allowed = list(/obj/item/weapon/storage/fancy/cigarettes,/obj/item/stack/spacecash) - flags_inv = HIDEJUMPSUIT - - -/obj/item/clothing/suit/apron/overalls - name = "coveralls" - desc = "A set of denim overalls." - icon_state = "overalls" - item_state = "overalls" - body_parts_covered = CHEST|GROIN|LEGS - - -/obj/item/clothing/suit/syndicatefake - name = "black and red space suit replica" - icon_state = "syndicate-black-red" - item_state = "syndicate-black-red" - desc = "A plastic replica of the Syndicate space suit. You'll look just like a real murderous Syndicate agent in this! This is a toy, it is not made for use in space!" - w_class = WEIGHT_CLASS_NORMAL - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy) - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - resistance_flags = 0 - -/obj/item/clothing/suit/hastur - name = "\improper Hastur's robe" - desc = "Robes not meant to be worn by man." - icon_state = "hastur" - item_state = "hastur" - body_parts_covered = CHEST|GROIN|LEGS|ARMS - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - - -/obj/item/clothing/suit/imperium_monk - name = "\improper Imperium monk suit" - desc = "Have YOU killed a xeno today?" - icon_state = "imperium_monk" - item_state = "imperium_monk" - body_parts_covered = CHEST|GROIN|LEGS|ARMS - flags_inv = HIDESHOES|HIDEJUMPSUIT - allowed = list(/obj/item/weapon/storage/book/bible, /obj/item/weapon/nullrod, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, /obj/item/weapon/storage/fancy/candle_box, /obj/item/candle, /obj/item/weapon/tank/internals/emergency_oxygen) - - -/obj/item/clothing/suit/chickensuit - name = "chicken suit" - desc = "A suit made long ago by the ancient empire KFC." - icon_state = "chickensuit" - item_state = "chickensuit" - body_parts_covered = CHEST|ARMS|GROIN|LEGS|FEET - flags_inv = HIDESHOES|HIDEJUMPSUIT - - -/obj/item/clothing/suit/monkeysuit - name = "monkey suit" - desc = "A suit that looks like a primate." - icon_state = "monkeysuit" - item_state = "monkeysuit" - body_parts_covered = CHEST|ARMS|GROIN|LEGS|FEET|HANDS - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - -/obj/item/clothing/suit/toggle/owlwings - name = "owl cloak" - desc = "A soft brown cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive the ladies mad." - icon_state = "owl_wings" - item_state = "owl_wings" - togglename = "wings" - body_parts_covered = ARMS|CHEST - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/ballistic,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/classic_baton/telescopic) - actions_types = list(/datum/action/item_action/toggle_wings) - -/obj/item/clothing/suit/toggle/owlwings/griffinwings - name = "griffon cloak" - desc = "A plush white cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive your captives mad." - icon_state = "griffin_wings" - item_state = "griffin_wings" - - -/obj/item/clothing/suit/holidaypriest - name = "holiday priest" - desc = "This is a nice holiday, my son." - icon_state = "holidaypriest" - item_state = "w_suit" - body_parts_covered = CHEST|GROIN|LEGS|ARMS - flags_inv = HIDEJUMPSUIT - allowed = list(/obj/item/weapon/storage/book/bible, /obj/item/weapon/nullrod, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, /obj/item/weapon/storage/fancy/candle_box, /obj/item/candle, /obj/item/weapon/tank/internals/emergency_oxygen) - -/obj/item/clothing/suit/cardborg - name = "cardborg suit" - desc = "An ordinary cardboard box with holes cut in the sides." - icon_state = "cardborg" - item_state = "cardborg" - body_parts_covered = CHEST|GROIN - flags_inv = HIDEJUMPSUIT - dog_fashion = /datum/dog_fashion/back - -/obj/item/clothing/suit/cardborg/equipped(mob/living/user, slot) - ..() - if(slot == slot_wear_suit) - disguise(user) - -/obj/item/clothing/suit/cardborg/dropped(mob/living/user) - ..() - user.remove_alt_appearance("standard_borg_disguise") - -/obj/item/clothing/suit/cardborg/proc/disguise(mob/living/carbon/human/H, obj/item/clothing/head/cardborg/borghead) - if(istype(H)) - if(!borghead) - borghead = H.head - if(istype(borghead, /obj/item/clothing/head/cardborg)) //why is this done this way? because equipped() is called BEFORE THE ITEM IS IN THE SLOT WHYYYY - var/image/I = image(icon = 'icons/mob/robots.dmi' , icon_state = "robot", loc = H) - I.override = 1 - I.add_overlay(image(icon = 'icons/mob/robots.dmi' , icon_state = "robot_e")) //gotta look realistic +/* + * Contains: + * Lasertag + * Costume + * Misc + */ + +/* + * Lasertag + */ +/obj/item/clothing/suit/bluetag + name = "blue laser tag armor" + desc = "A piece of plastic armor. It has sensors that react to red light." //Lasers are concentrated light + icon_state = "bluetag" + item_state = "bluetag" + blood_overlay_type = "armor" + body_parts_covered = CHEST + allowed = list (/obj/item/weapon/gun/energy/laser/bluetag) + resistance_flags = 0 + +/obj/item/clothing/suit/redtag + name = "red laser tag armor" + desc = "A piece of plastic armor. It has sensors that react to blue light." + icon_state = "redtag" + item_state = "redtag" + blood_overlay_type = "armor" + body_parts_covered = CHEST + allowed = list (/obj/item/weapon/gun/energy/laser/redtag) + resistance_flags = 0 + +/* + * Costume + */ +/obj/item/clothing/suit/pirate + name = "pirate coat" + desc = "Yarr." + icon_state = "pirate" + item_state = "pirate" + allowed = list(/obj/item/weapon/melee/energy/sword/pirate, /obj/item/clothing/glasses/eyepatch, /obj/item/weapon/reagent_containers/food/drinks/bottle/rum) + +/obj/item/clothing/suit/pirate/captain + name = "pirate captain coat" + desc = "Yarr." + icon_state = "hgpirate" + item_state = "hgpirate" + + +/obj/item/clothing/suit/cyborg_suit + name = "cyborg suit" + desc = "Suit for a cyborg costume." + icon_state = "death" + item_state = "death" + flags = CONDUCT + fire_resist = T0C+5200 + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + + +/obj/item/clothing/suit/justice + name = "justice suit" + desc = "this pretty much looks ridiculous" //Needs no fixing + icon_state = "justice" + item_state = "justice" + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + + +/obj/item/clothing/suit/judgerobe + name = "judge's robe" + desc = "This robe commands authority." + icon_state = "judge" + item_state = "judge" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + allowed = list(/obj/item/weapon/storage/fancy/cigarettes,/obj/item/stack/spacecash) + flags_inv = HIDEJUMPSUIT + + +/obj/item/clothing/suit/apron/overalls + name = "coveralls" + desc = "A set of denim overalls." + icon_state = "overalls" + item_state = "overalls" + body_parts_covered = CHEST|GROIN|LEGS + + +/obj/item/clothing/suit/syndicatefake + name = "black and red space suit replica" + icon_state = "syndicate-black-red" + item_state = "syndicate-black-red" + desc = "A plastic replica of the Syndicate space suit. You'll look just like a real murderous Syndicate agent in this! This is a toy, it is not made for use in space!" + w_class = WEIGHT_CLASS_NORMAL + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy) + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + resistance_flags = 0 + +/obj/item/clothing/suit/hastur + name = "\improper Hastur's robe" + desc = "Robes not meant to be worn by man." + icon_state = "hastur" + item_state = "hastur" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + + +/obj/item/clothing/suit/imperium_monk + name = "\improper Imperium monk suit" + desc = "Have YOU killed a xeno today?" + icon_state = "imperium_monk" + item_state = "imperium_monk" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + flags_inv = HIDESHOES|HIDEJUMPSUIT + allowed = list(/obj/item/weapon/storage/book/bible, /obj/item/weapon/nullrod, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, /obj/item/weapon/storage/fancy/candle_box, /obj/item/candle, /obj/item/weapon/tank/internals/emergency_oxygen) + + +/obj/item/clothing/suit/chickensuit + name = "chicken suit" + desc = "A suit made long ago by the ancient empire KFC." + icon_state = "chickensuit" + item_state = "chickensuit" + body_parts_covered = CHEST|ARMS|GROIN|LEGS|FEET + flags_inv = HIDESHOES|HIDEJUMPSUIT + + +/obj/item/clothing/suit/monkeysuit + name = "monkey suit" + desc = "A suit that looks like a primate." + icon_state = "monkeysuit" + item_state = "monkeysuit" + body_parts_covered = CHEST|ARMS|GROIN|LEGS|FEET|HANDS + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + +/obj/item/clothing/suit/toggle/owlwings + name = "owl cloak" + desc = "A soft brown cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive the ladies mad." + icon_state = "owl_wings" + item_state = "owl_wings" + togglename = "wings" + body_parts_covered = ARMS|CHEST + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/ballistic,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/classic_baton/telescopic) + actions_types = list(/datum/action/item_action/toggle_wings) + +/obj/item/clothing/suit/toggle/owlwings/griffinwings + name = "griffon cloak" + desc = "A plush white cloak made of synthetic feathers. Soft to the touch, stylish, and a 2 meter wing span that will drive your captives mad." + icon_state = "griffin_wings" + item_state = "griffin_wings" + + +/obj/item/clothing/suit/holidaypriest + name = "holiday priest" + desc = "This is a nice holiday, my son." + icon_state = "holidaypriest" + item_state = "w_suit" + body_parts_covered = CHEST|GROIN|LEGS|ARMS + flags_inv = HIDEJUMPSUIT + allowed = list(/obj/item/weapon/storage/book/bible, /obj/item/weapon/nullrod, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, /obj/item/weapon/storage/fancy/candle_box, /obj/item/candle, /obj/item/weapon/tank/internals/emergency_oxygen) + +/obj/item/clothing/suit/cardborg + name = "cardborg suit" + desc = "An ordinary cardboard box with holes cut in the sides." + icon_state = "cardborg" + item_state = "cardborg" + body_parts_covered = CHEST|GROIN + flags_inv = HIDEJUMPSUIT + dog_fashion = /datum/dog_fashion/back + +/obj/item/clothing/suit/cardborg/equipped(mob/living/user, slot) + ..() + if(slot == slot_wear_suit) + disguise(user) + +/obj/item/clothing/suit/cardborg/dropped(mob/living/user) + ..() + user.remove_alt_appearance("standard_borg_disguise") + +/obj/item/clothing/suit/cardborg/proc/disguise(mob/living/carbon/human/H, obj/item/clothing/head/cardborg/borghead) + if(istype(H)) + if(!borghead) + borghead = H.head + if(istype(borghead, /obj/item/clothing/head/cardborg)) //why is this done this way? because equipped() is called BEFORE THE ITEM IS IN THE SLOT WHYYYY + var/image/I = image(icon = 'icons/mob/robots.dmi' , icon_state = "robot", loc = H) + I.override = 1 + I.add_overlay(mutable_appearance('icons/mob/robots.dmi', "robot_e")) //gotta look realistic add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/silicons, "standard_borg_disguise", I) //you look like a robot to robots! (including yourself because you're totally a robot) - - -/obj/item/clothing/suit/snowman - name = "snowman outfit" - desc = "Two white spheres covered in white glitter. 'Tis the season." - icon_state = "snowman" - item_state = "snowman" - body_parts_covered = CHEST|GROIN - flags_inv = HIDEJUMPSUIT - -/obj/item/clothing/suit/poncho - name = "poncho" - desc = "Your classic, non-racist poncho." - icon_state = "classicponcho" - item_state = "classicponcho" - -/obj/item/clothing/suit/poncho/green - name = "green poncho" - desc = "Your classic, non-racist poncho. This one is green." - icon_state = "greenponcho" - item_state = "greenponcho" - -/obj/item/clothing/suit/poncho/red - name = "red poncho" - desc = "Your classic, non-racist poncho. This one is red." - icon_state = "redponcho" - item_state = "redponcho" - -/obj/item/clothing/suit/poncho/ponchoshame - name = "poncho of shame" - desc = "Forced to live on your shameful acting as a fake Mexican, you and your poncho have grown inseperable. Literally." - icon_state = "ponchoshame" - item_state = "ponchoshame" - flags = NODROP - -/obj/item/clothing/suit/whitedress - name = "white dress" - desc = "A fancy white dress." - icon_state = "white_dress" - item_state = "w_suit" - body_parts_covered = CHEST|GROIN|LEGS|FEET - flags_inv = HIDEJUMPSUIT|HIDESHOES - -/obj/item/clothing/suit/hooded/carp_costume - name = "carp costume" - desc = "A costume made from 'synthetic' carp scales, it smells." - icon_state = "carp_casual" - item_state = "labcoat" - body_parts_covered = CHEST|GROIN|ARMS - cold_protection = CHEST|GROIN|ARMS - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT //Space carp like space, so you should too - allowed = list(/obj/item/weapon/tank/internals/emergency_oxygen, /obj/item/weapon/gun/ballistic/automatic/speargun) - hoodtype = /obj/item/clothing/head/hooded/carp_hood - -/obj/item/clothing/head/hooded/carp_hood - name = "carp hood" - desc = "A hood attached to a carp costume." - icon_state = "carp_casual" - body_parts_covered = HEAD - cold_protection = HEAD - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - flags_inv = HIDEHAIR|HIDEEARS - -/obj/item/clothing/suit/hooded/ian_costume //It's Ian, rub his bell- oh god what happened to his inside parts? - name = "corgi costume" - desc = "A costume that looks like someone made a human-like corgi, it won't guarantee belly rubs." - icon_state = "ian" - item_state = "labcoat" - body_parts_covered = CHEST|GROIN|ARMS - //cold_protection = CHEST|GROIN|ARMS - //min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - allowed = list() - hoodtype = /obj/item/clothing/head/hooded/ian_hood - dog_fashion = /datum/dog_fashion/back - -/obj/item/clothing/head/hooded/ian_hood - name = "corgi hood" - desc = "A hood that looks just like a corgi's head, it won't guarantee dog biscuits." - icon_state = "ian" - body_parts_covered = HEAD - //cold_protection = HEAD - //min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - flags_inv = HIDEHAIR|HIDEEARS - -/obj/item/clothing/suit/hooded/bee_costume // It's Hip! - name = "bee costume" - desc = "Bee the true Queen!" - icon_state = "bee" - item_state = "labcoat" - body_parts_covered = CHEST|GROIN|ARMS - flags = THICKMATERIAL - hoodtype = /obj/item/clothing/head/hooded/bee_hood - -/obj/item/clothing/head/hooded/bee_hood - name = "bee hood" - desc = "A hood attached to a bee costume." - icon_state = "bee" - body_parts_covered = HEAD - flags = THICKMATERIAL - flags_inv = HIDEHAIR|HIDEEARS - -/obj/item/clothing/suit/hooded/bloated_human //OH MY GOD WHAT HAVE YOU DONE!?!?!? - name = "bloated human suit" - desc = "A horribly bloated suit made from human skins." - icon_state = "lingspacesuit" - item_state = "labcoat" - body_parts_covered = CHEST|GROIN|ARMS - allowed = list() - actions_types = list(/datum/action/item_action/toggle_human_head) - hoodtype = /obj/item/clothing/head/hooded/human_head - - -/obj/item/clothing/head/hooded/human_head - name = "bloated human head" - desc = "A horribly bloated and mismatched human head." - icon_state = "lingspacehelmet" - body_parts_covered = HEAD - flags_cover = HEADCOVERSEYES - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR - -/obj/item/clothing/suit/security/officer/russian - name = "russian officer's jacket" - desc = "This jacket is for those special occasions when a russian officer isn't required to wear their armor." - icon_state = "officertanjacket" - item_state = "officertanjacket" - body_parts_covered = CHEST|ARMS - -/* - * Misc - */ - -/obj/item/clothing/suit/straight_jacket - name = "straight jacket" - desc = "A suit that completely restrains the wearer. Manufactured by Antyphun Corp." //Straight jacket is antifun - icon_state = "straight_jacket" - item_state = "straight_jacket" - body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - strip_delay = 60 - breakouttime = 3000 - -/obj/item/clothing/suit/ianshirt - name = "worn shirt" - desc = "A worn out, curiously comfortable t-shirt with a picture of Ian. You wouldn't go so far as to say it feels like being hugged when you wear it, but it's pretty close. Good for sleeping in." - icon_state = "ianshirt" - item_state = "ianshirt" - -/obj/item/clothing/suit/nerdshirt - name = "gamer shirt" - desc = "A baggy shirt with vintage game character Phanic the Weasel. Why would anyone wear this?" - icon_state = "nerdshirt" - item_state = "nerdshirt" - -/obj/item/clothing/suit/vapeshirt //wearing this is asking to get beat. - name = "Vape Naysh shirt" - desc = "A cheap white T-shirt with a big tacky \"VN\" on the front, Why would you wear this unironicly?" - icon_state = "vapeshirt" - item_state = "vapeshirt" - -/obj/item/clothing/suit/jacket - name = "bomber jacket" - desc = "Aviators not included." - icon_state = "bomberjacket" - item_state = "brownjsuit" - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/radio) - body_parts_covered = CHEST|GROIN|ARMS - cold_protection = CHEST|GROIN|ARMS - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - -/obj/item/clothing/suit/jacket/leather - name = "leather jacket" - desc = "Pompadour not included." - icon_state = "leatherjacket" - item_state = "hostrench" - resistance_flags = 0 - max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/weapon/gun/ballistic/automatic/pistol,/obj/item/weapon/gun/ballistic/revolver,/obj/item/weapon/gun/ballistic/revolver/detective,/obj/item/device/radio) - -/obj/item/clothing/suit/jacket/leather/overcoat - name = "leather overcoat" - desc = "That's a damn fine coat." - icon_state = "leathercoat" - body_parts_covered = CHEST|GROIN|ARMS|LEGS - cold_protection = CHEST|GROIN|ARMS|LEGS - -/obj/item/clothing/suit/jacket/puffer - name = "puffer jacket" - desc = "A thick jacket with a rubbery, water-resistant shell." - icon_state = "pufferjacket" - item_state = "hostrench" - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0, fire = 0, acid = 0) - -/obj/item/clothing/suit/jacket/puffer/vest - name = "puffer vest" - desc = "A thick vest with a rubbery, water-resistant shell." - icon_state = "puffervest" - item_state = "armor" - body_parts_covered = CHEST|GROIN - cold_protection = CHEST|GROIN - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 30, rad = 0, fire = 0, acid = 0) - -/obj/item/clothing/suit/jacket/miljacket - name = "military jacket" - desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable." - icon_state = "militaryjacket" - item_state = "militaryjacket" - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/weapon/gun/ballistic/automatic/pistol,/obj/item/weapon/gun/ballistic/revolver,/obj/item/weapon/gun/ballistic/revolver/detective,/obj/item/device/radio) - -/obj/item/clothing/suit/jacket/letterman - name = "letterman jacket" - desc = "A classic brown letterman jacket. Looks pretty hot and heavy." - icon_state = "letterman" - item_state = "letterman" - -/obj/item/clothing/suit/jacket/letterman_red - name = "red letterman jacket" - desc = "A letterman jacket in a sick red color. Radical." - icon_state = "letterman_red" - item_state = "letterman_red" - -/obj/item/clothing/suit/jacket/letterman_syndie - name = "blood-red letterman jacket" - desc = "Oddly, this jacket seems to have a large S on the back..." - icon_state = "letterman_s" - item_state = "letterman_s" - -/obj/item/clothing/suit/jacket/letterman_nanotrasen - name = "blue letterman jacket" - desc = "A blue letterman jacket with a proud Nanotrasen N on the back. The tag says that it was made in Space China." - icon_state = "letterman_n" - item_state = "letterman_n" - -/obj/item/clothing/suit/xenos - name = "xenos suit" - desc = "A suit made out of chitinous alien hide." - icon_state = "xenos" - item_state = "xenos_helm" - body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - allowed = list(/obj/item/clothing/mask/facehugger/toy) - - -// WINTER COATS - -/obj/item/clothing/suit/hooded/wintercoat - name = "winter coat" - desc = "A heavy jacket made from 'synthetic' animal furs." - icon_state = "coatwinter" - item_state = "coatwinter" - body_parts_covered = CHEST|GROIN|ARMS - cold_protection = CHEST|GROIN|ARMS - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0, fire = 0, acid = 0) - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter) - -/obj/item/clothing/head/hooded/winterhood - name = "winter hood" - desc = "A hood attached to a heavy winter jacket." - icon_state = "winterhood" - body_parts_covered = HEAD - cold_protection = HEAD - min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT - flags_inv = HIDEHAIR|HIDEEARS - -/obj/item/clothing/suit/hooded/wintercoat/captain - name = "captain's winter coat" - icon_state = "coatcaptain" - item_state = "coatcaptain" - armor = list(melee = 25, bullet = 30, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0, fire = 0, acid = 50) - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/ballistic,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/classic_baton/telescopic) - hoodtype = /obj/item/clothing/head/hooded/winterhood/captain - -/obj/item/clothing/head/hooded/winterhood/captain - icon_state = "winterhood_captain" - -/obj/item/clothing/suit/hooded/wintercoat/security - name = "security winter coat" - icon_state = "coatsecurity" - item_state = "coatsecurity" - armor = list(melee = 25, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0, fire = 0, acid = 45) - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/ballistic,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/classic_baton/telescopic) - hoodtype = /obj/item/clothing/head/hooded/winterhood/security - -/obj/item/clothing/head/hooded/winterhood/security - icon_state = "winterhood_security" - -/obj/item/clothing/suit/hooded/wintercoat/medical - name = "medical winter coat" - icon_state = "coatmedical" - item_state = "coatmedical" - allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper,/obj/item/weapon/melee/classic_baton/telescopic) - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0, fire = 0, acid = 45) - hoodtype = /obj/item/clothing/head/hooded/winterhood/medical - -/obj/item/clothing/head/hooded/winterhood/medical - icon_state = "winterhood_medical" - -/obj/item/clothing/suit/hooded/wintercoat/science - name = "science winter coat" - icon_state = "coatscience" - item_state = "coatscience" - allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper,/obj/item/weapon/melee/classic_baton/telescopic) - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 10, bio = 0, rad = 0, fire = 0, acid = 0) - hoodtype = /obj/item/clothing/head/hooded/winterhood/science - -/obj/item/clothing/head/hooded/winterhood/science - icon_state = "winterhood_science" - -/obj/item/clothing/suit/hooded/wintercoat/engineering - name = "engineering winter coat" - icon_state = "coatengineer" - item_state = "coatengineer" - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 20, fire = 30, acid = 45) - allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/device/t_scanner, /obj/item/weapon/construction/rcd, /obj/item/weapon/pipe_dispenser) - hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering - -/obj/item/clothing/head/hooded/winterhood/engineering - icon_state = "winterhood_engineer" - -/obj/item/clothing/suit/hooded/wintercoat/engineering/atmos - name = "atmospherics winter coat" - icon_state = "coatatmos" - item_state = "coatatmos" - hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering/atmos - -/obj/item/clothing/head/hooded/winterhood/engineering/atmos - icon_state = "winterhood_atmos" - -/obj/item/clothing/suit/hooded/wintercoat/hydro - name = "hydroponics winter coat" - icon_state = "coathydro" - item_state = "coathydro" - allowed = list(/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/device/plant_analyzer,/obj/item/seeds,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/cultivator,/obj/item/weapon/reagent_containers/spray/pestspray,/obj/item/weapon/hatchet,/obj/item/weapon/storage/bag/plants) - hoodtype = /obj/item/clothing/head/hooded/winterhood/hydro - -/obj/item/clothing/head/hooded/winterhood/hydro - icon_state = "winterhood_hydro" - -/obj/item/clothing/suit/hooded/wintercoat/cargo - name = "cargo winter coat" - icon_state = "coatcargo" - item_state = "coatcargo" - hoodtype = /obj/item/clothing/head/hooded/winterhood/cargo - -/obj/item/clothing/head/hooded/winterhood/cargo - icon_state = "winterhood_cargo" - -/obj/item/clothing/suit/hooded/wintercoat/miner - name = "mining winter coat" - icon_state = "coatminer" - item_state = "coatminer" - allowed = list(/obj/item/weapon/pickaxe,/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter) - armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) - hoodtype = /obj/item/clothing/head/hooded/winterhood/miner - -/obj/item/clothing/head/hooded/winterhood/miner - icon_state = "winterhood_miner" - -/obj/item/clothing/suit/spookyghost - name = "spooky ghost" - desc = "this is obviously just a bedsheet, but maybe try it on?" - icon_state = "bedsheet" - user_vars_to_edit = list("name" = "Spooky Ghost", "real_name" = "Spooky Ghost" , "incorporeal_move" = 1, "appearance_flags" = KEEP_TOGETHER|TILE_BOUND, "alpha" = 150) - alternate_worn_layer = ABOVE_BODY_FRONT_LAYER //so the bedsheet goes over everything but fire + +/obj/item/clothing/suit/snowman + name = "snowman outfit" + desc = "Two white spheres covered in white glitter. 'Tis the season." + icon_state = "snowman" + item_state = "snowman" + body_parts_covered = CHEST|GROIN + flags_inv = HIDEJUMPSUIT + +/obj/item/clothing/suit/poncho + name = "poncho" + desc = "Your classic, non-racist poncho." + icon_state = "classicponcho" + item_state = "classicponcho" + +/obj/item/clothing/suit/poncho/green + name = "green poncho" + desc = "Your classic, non-racist poncho. This one is green." + icon_state = "greenponcho" + item_state = "greenponcho" + +/obj/item/clothing/suit/poncho/red + name = "red poncho" + desc = "Your classic, non-racist poncho. This one is red." + icon_state = "redponcho" + item_state = "redponcho" + +/obj/item/clothing/suit/poncho/ponchoshame + name = "poncho of shame" + desc = "Forced to live on your shameful acting as a fake Mexican, you and your poncho have grown inseperable. Literally." + icon_state = "ponchoshame" + item_state = "ponchoshame" + flags = NODROP + +/obj/item/clothing/suit/whitedress + name = "white dress" + desc = "A fancy white dress." + icon_state = "white_dress" + item_state = "w_suit" + body_parts_covered = CHEST|GROIN|LEGS|FEET + flags_inv = HIDEJUMPSUIT|HIDESHOES + +/obj/item/clothing/suit/hooded/carp_costume + name = "carp costume" + desc = "A costume made from 'synthetic' carp scales, it smells." + icon_state = "carp_casual" + item_state = "labcoat" + body_parts_covered = CHEST|GROIN|ARMS + cold_protection = CHEST|GROIN|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT //Space carp like space, so you should too + allowed = list(/obj/item/weapon/tank/internals/emergency_oxygen, /obj/item/weapon/gun/ballistic/automatic/speargun) + hoodtype = /obj/item/clothing/head/hooded/carp_hood + +/obj/item/clothing/head/hooded/carp_hood + name = "carp hood" + desc = "A hood attached to a carp costume." + icon_state = "carp_casual" + body_parts_covered = HEAD + cold_protection = HEAD + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + flags_inv = HIDEHAIR|HIDEEARS + +/obj/item/clothing/suit/hooded/ian_costume //It's Ian, rub his bell- oh god what happened to his inside parts? + name = "corgi costume" + desc = "A costume that looks like someone made a human-like corgi, it won't guarantee belly rubs." + icon_state = "ian" + item_state = "labcoat" + body_parts_covered = CHEST|GROIN|ARMS + //cold_protection = CHEST|GROIN|ARMS + //min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + allowed = list() + hoodtype = /obj/item/clothing/head/hooded/ian_hood + dog_fashion = /datum/dog_fashion/back + +/obj/item/clothing/head/hooded/ian_hood + name = "corgi hood" + desc = "A hood that looks just like a corgi's head, it won't guarantee dog biscuits." + icon_state = "ian" + body_parts_covered = HEAD + //cold_protection = HEAD + //min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + flags_inv = HIDEHAIR|HIDEEARS + +/obj/item/clothing/suit/hooded/bee_costume // It's Hip! + name = "bee costume" + desc = "Bee the true Queen!" + icon_state = "bee" + item_state = "labcoat" + body_parts_covered = CHEST|GROIN|ARMS + flags = THICKMATERIAL + hoodtype = /obj/item/clothing/head/hooded/bee_hood + +/obj/item/clothing/head/hooded/bee_hood + name = "bee hood" + desc = "A hood attached to a bee costume." + icon_state = "bee" + body_parts_covered = HEAD + flags = THICKMATERIAL + flags_inv = HIDEHAIR|HIDEEARS + +/obj/item/clothing/suit/hooded/bloated_human //OH MY GOD WHAT HAVE YOU DONE!?!?!? + name = "bloated human suit" + desc = "A horribly bloated suit made from human skins." + icon_state = "lingspacesuit" + item_state = "labcoat" + body_parts_covered = CHEST|GROIN|ARMS + allowed = list() + actions_types = list(/datum/action/item_action/toggle_human_head) + hoodtype = /obj/item/clothing/head/hooded/human_head + + +/obj/item/clothing/head/hooded/human_head + name = "bloated human head" + desc = "A horribly bloated and mismatched human head." + icon_state = "lingspacehelmet" + body_parts_covered = HEAD + flags_cover = HEADCOVERSEYES + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + +/obj/item/clothing/suit/security/officer/russian + name = "russian officer's jacket" + desc = "This jacket is for those special occasions when a russian officer isn't required to wear their armor." + icon_state = "officertanjacket" + item_state = "officertanjacket" + body_parts_covered = CHEST|ARMS + +/* + * Misc + */ + +/obj/item/clothing/suit/straight_jacket + name = "straight jacket" + desc = "A suit that completely restrains the wearer. Manufactured by Antyphun Corp." //Straight jacket is antifun + icon_state = "straight_jacket" + item_state = "straight_jacket" + body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + strip_delay = 60 + breakouttime = 3000 + +/obj/item/clothing/suit/ianshirt + name = "worn shirt" + desc = "A worn out, curiously comfortable t-shirt with a picture of Ian. You wouldn't go so far as to say it feels like being hugged when you wear it, but it's pretty close. Good for sleeping in." + icon_state = "ianshirt" + item_state = "ianshirt" + +/obj/item/clothing/suit/nerdshirt + name = "gamer shirt" + desc = "A baggy shirt with vintage game character Phanic the Weasel. Why would anyone wear this?" + icon_state = "nerdshirt" + item_state = "nerdshirt" + +/obj/item/clothing/suit/vapeshirt //wearing this is asking to get beat. + name = "Vape Naysh shirt" + desc = "A cheap white T-shirt with a big tacky \"VN\" on the front, Why would you wear this unironicly?" + icon_state = "vapeshirt" + item_state = "vapeshirt" + +/obj/item/clothing/suit/jacket + name = "bomber jacket" + desc = "Aviators not included." + icon_state = "bomberjacket" + item_state = "brownjsuit" + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/device/radio) + body_parts_covered = CHEST|GROIN|ARMS + cold_protection = CHEST|GROIN|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + +/obj/item/clothing/suit/jacket/leather + name = "leather jacket" + desc = "Pompadour not included." + icon_state = "leatherjacket" + item_state = "hostrench" + resistance_flags = 0 + max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/weapon/gun/ballistic/automatic/pistol,/obj/item/weapon/gun/ballistic/revolver,/obj/item/weapon/gun/ballistic/revolver/detective,/obj/item/device/radio) + +/obj/item/clothing/suit/jacket/leather/overcoat + name = "leather overcoat" + desc = "That's a damn fine coat." + icon_state = "leathercoat" + body_parts_covered = CHEST|GROIN|ARMS|LEGS + cold_protection = CHEST|GROIN|ARMS|LEGS + +/obj/item/clothing/suit/jacket/puffer + name = "puffer jacket" + desc = "A thick jacket with a rubbery, water-resistant shell." + icon_state = "pufferjacket" + item_state = "hostrench" + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0, fire = 0, acid = 0) + +/obj/item/clothing/suit/jacket/puffer/vest + name = "puffer vest" + desc = "A thick vest with a rubbery, water-resistant shell." + icon_state = "puffervest" + item_state = "armor" + body_parts_covered = CHEST|GROIN + cold_protection = CHEST|GROIN + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 30, rad = 0, fire = 0, acid = 0) + +/obj/item/clothing/suit/jacket/miljacket + name = "military jacket" + desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable." + icon_state = "militaryjacket" + item_state = "militaryjacket" + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter,/obj/item/weapon/gun/ballistic/automatic/pistol,/obj/item/weapon/gun/ballistic/revolver,/obj/item/weapon/gun/ballistic/revolver/detective,/obj/item/device/radio) + +/obj/item/clothing/suit/jacket/letterman + name = "letterman jacket" + desc = "A classic brown letterman jacket. Looks pretty hot and heavy." + icon_state = "letterman" + item_state = "letterman" + +/obj/item/clothing/suit/jacket/letterman_red + name = "red letterman jacket" + desc = "A letterman jacket in a sick red color. Radical." + icon_state = "letterman_red" + item_state = "letterman_red" + +/obj/item/clothing/suit/jacket/letterman_syndie + name = "blood-red letterman jacket" + desc = "Oddly, this jacket seems to have a large S on the back..." + icon_state = "letterman_s" + item_state = "letterman_s" + +/obj/item/clothing/suit/jacket/letterman_nanotrasen + name = "blue letterman jacket" + desc = "A blue letterman jacket with a proud Nanotrasen N on the back. The tag says that it was made in Space China." + icon_state = "letterman_n" + item_state = "letterman_n" + +/obj/item/clothing/suit/xenos + name = "xenos suit" + desc = "A suit made out of chitinous alien hide." + icon_state = "xenos" + item_state = "xenos_helm" + body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS + flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT + allowed = list(/obj/item/clothing/mask/facehugger/toy) + + +// WINTER COATS + +/obj/item/clothing/suit/hooded/wintercoat + name = "winter coat" + desc = "A heavy jacket made from 'synthetic' animal furs." + icon_state = "coatwinter" + item_state = "coatwinter" + body_parts_covered = CHEST|GROIN|ARMS + cold_protection = CHEST|GROIN|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0, fire = 0, acid = 0) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter) + +/obj/item/clothing/head/hooded/winterhood + name = "winter hood" + desc = "A hood attached to a heavy winter jacket." + icon_state = "winterhood" + body_parts_covered = HEAD + cold_protection = HEAD + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + flags_inv = HIDEHAIR|HIDEEARS + +/obj/item/clothing/suit/hooded/wintercoat/captain + name = "captain's winter coat" + icon_state = "coatcaptain" + item_state = "coatcaptain" + armor = list(melee = 25, bullet = 30, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0, fire = 0, acid = 50) + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/ballistic,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/classic_baton/telescopic) + hoodtype = /obj/item/clothing/head/hooded/winterhood/captain + +/obj/item/clothing/head/hooded/winterhood/captain + icon_state = "winterhood_captain" + +/obj/item/clothing/suit/hooded/wintercoat/security + name = "security winter coat" + icon_state = "coatsecurity" + item_state = "coatsecurity" + armor = list(melee = 25, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 0, rad = 0, fire = 0, acid = 45) + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/ballistic,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/classic_baton/telescopic) + hoodtype = /obj/item/clothing/head/hooded/winterhood/security + +/obj/item/clothing/head/hooded/winterhood/security + icon_state = "winterhood_security" + +/obj/item/clothing/suit/hooded/wintercoat/medical + name = "medical winter coat" + icon_state = "coatmedical" + item_state = "coatmedical" + allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper,/obj/item/weapon/melee/classic_baton/telescopic) + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0, fire = 0, acid = 45) + hoodtype = /obj/item/clothing/head/hooded/winterhood/medical + +/obj/item/clothing/head/hooded/winterhood/medical + icon_state = "winterhood_medical" + +/obj/item/clothing/suit/hooded/wintercoat/science + name = "science winter coat" + icon_state = "coatscience" + item_state = "coatscience" + allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper,/obj/item/weapon/melee/classic_baton/telescopic) + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 10, bio = 0, rad = 0, fire = 0, acid = 0) + hoodtype = /obj/item/clothing/head/hooded/winterhood/science + +/obj/item/clothing/head/hooded/winterhood/science + icon_state = "winterhood_science" + +/obj/item/clothing/suit/hooded/wintercoat/engineering + name = "engineering winter coat" + icon_state = "coatengineer" + item_state = "coatengineer" + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 20, fire = 30, acid = 45) + allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/device/t_scanner, /obj/item/weapon/construction/rcd, /obj/item/weapon/pipe_dispenser) + hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering + +/obj/item/clothing/head/hooded/winterhood/engineering + icon_state = "winterhood_engineer" + +/obj/item/clothing/suit/hooded/wintercoat/engineering/atmos + name = "atmospherics winter coat" + icon_state = "coatatmos" + item_state = "coatatmos" + hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering/atmos + +/obj/item/clothing/head/hooded/winterhood/engineering/atmos + icon_state = "winterhood_atmos" + +/obj/item/clothing/suit/hooded/wintercoat/hydro + name = "hydroponics winter coat" + icon_state = "coathydro" + item_state = "coathydro" + allowed = list(/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/device/plant_analyzer,/obj/item/seeds,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/cultivator,/obj/item/weapon/reagent_containers/spray/pestspray,/obj/item/weapon/hatchet,/obj/item/weapon/storage/bag/plants) + hoodtype = /obj/item/clothing/head/hooded/winterhood/hydro + +/obj/item/clothing/head/hooded/winterhood/hydro + icon_state = "winterhood_hydro" + +/obj/item/clothing/suit/hooded/wintercoat/cargo + name = "cargo winter coat" + icon_state = "coatcargo" + item_state = "coatcargo" + hoodtype = /obj/item/clothing/head/hooded/winterhood/cargo + +/obj/item/clothing/head/hooded/winterhood/cargo + icon_state = "winterhood_cargo" + +/obj/item/clothing/suit/hooded/wintercoat/miner + name = "mining winter coat" + icon_state = "coatminer" + item_state = "coatminer" + allowed = list(/obj/item/weapon/pickaxe,/obj/item/device/flashlight,/obj/item/weapon/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/lighter) + armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) + hoodtype = /obj/item/clothing/head/hooded/winterhood/miner + +/obj/item/clothing/head/hooded/winterhood/miner + icon_state = "winterhood_miner" + +/obj/item/clothing/suit/spookyghost + name = "spooky ghost" + desc = "this is obviously just a bedsheet, but maybe try it on?" + icon_state = "bedsheet" + user_vars_to_edit = list("name" = "Spooky Ghost", "real_name" = "Spooky Ghost" , "incorporeal_move" = 1, "appearance_flags" = KEEP_TOGETHER|TILE_BOUND, "alpha" = 150) + alternate_worn_layer = ABOVE_BODY_FRONT_LAYER //so the bedsheet goes over everything but fire diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm index 06110adb82..aa6368cfd6 100644 --- a/code/modules/detectivework/evidence.dm +++ b/code/modules/detectivework/evidence.dm @@ -47,15 +47,12 @@ icon_state = "evidence" - var/xx = I.pixel_x //save the offset of the item - var/yy = I.pixel_y - I.pixel_x = 0 //then remove it so it'll stay within the evidence bag - I.pixel_y = 0 - var/image/img = image("icon"=I, "layer"=FLOAT_LAYER) //take a snapshot. (necessary to stop the underlays appearing under our inventory-HUD slots ~Carn - img.plane = FLOAT_PLANE - I.pixel_x = xx //and then return it - I.pixel_y = yy - add_overlay(img) + var/mutable_appearance/in_evidence = new(I) + in_evidence.plane = FLOAT_PLANE + in_evidence.layer = FLOAT_LAYER + in_evidence.pixel_x = 0 + in_evidence.pixel_y = 0 + add_overlay(in_evidence) add_overlay("evidence") //should look nicer for transparent stuff. not really that important, but hey. desc = "An evidence bag containing [I]. [I.desc]" diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm index 8f95552a4b..888b87cc02 100644 --- a/code/modules/events/portal_storm.dm +++ b/code/modules/events/portal_storm.dm @@ -34,10 +34,10 @@ var/list/hostile_types = list() var/number_of_hostiles var/list/station_areas = list() - var/image/storm + var/mutable_appearance/storm /datum/round_event/portal_storm/setup() - storm = image('icons/obj/tesla_engine/energy_ball.dmi', "energy_ball_fast", layer=FLY_LAYER) + storm = storm = mutable_appearance('icons/obj/tesla_engine/energy_ball.dmi', "energy_ball_fast", FLY_LAYER) storm.color = "#00FF00" station_areas = get_areas_in_z(ZLEVEL_STATION) diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm index 7e2deff368..1e2710afb6 100644 --- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm +++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm @@ -22,9 +22,9 @@ if(R.glass_icon_state) icon_state = R.glass_icon_state else - var/image/I = image(icon, "glassoverlay") - I.color = mix_color_from_reagents(reagents.reagent_list) - add_overlay(I) + var/mutable_appearance/reagent_overlay = mutable_appearance(icon, "glassoverlay") + reagent_overlay.color = mix_color_from_reagents(reagents.reagent_list) + add_overlay(reagent_overlay) else icon_state = "glass_empty" name = "drinking glass" @@ -64,9 +64,9 @@ icon_state = largest_reagent.shot_glass_icon_state else icon_state = "shotglassclear" - var/image/I = image(icon, "shotglassoverlay") - I.color = mix_color_from_reagents(reagents.reagent_list) - add_overlay(I) + var/mutable_appearance/shot_overlay = mutable_appearance(icon, "shotglassoverlay") + shot_overlay.color = mix_color_from_reagents(reagents.reagent_list) + add_overlay(shot_overlay) else diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 705319f7c3..3a6c2d91f6 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -101,37 +101,36 @@ filling_color = rgb(rgbcolor[1], rgbcolor[2], rgbcolor[3], rgbcolor[4]) /obj/item/weapon/reagent_containers/food/snacks/customizable/update_overlays(obj/item/weapon/reagent_containers/food/snacks/S) - var/image/I = new(icon, "[initial(icon_state)]_filling") + var/mutable_appearance/filling = mutable_appearance(icon, "[initial(icon_state)]_filling") if(S.filling_color == "#FFFFFF") - I.color = pick("#FF0000","#0000FF","#008000","#FFFF00") + filling.color = pick("#FF0000","#0000FF","#008000","#FFFF00") else - I.color = S.filling_color + filling.color = S.filling_color switch(ingredients_placement) if(INGREDIENTS_SCATTER) - I.pixel_x = rand(-1,1) - I.pixel_y = rand(-1,1) + filling.pixel_x = rand(-1,1) + filling.pixel_y = rand(-1,1) if(INGREDIENTS_STACK) - I.pixel_x = rand(-1,1) - I.pixel_y = 2 * ingredients.len - 1 + filling.pixel_x = rand(-1,1) + filling.pixel_y = 2 * ingredients.len - 1 if(INGREDIENTS_STACKPLUSTOP) - I.pixel_x = rand(-1,1) - I.pixel_y = 2 * ingredients.len - 1 + filling.pixel_x = rand(-1,1) + filling.pixel_y = 2 * ingredients.len - 1 if(our_overlays) our_overlays.Cut(ingredients.len) //???, add overlay calls later in this proc will queue the compile if necessary - var/image/TOP = new(icon, "[icon_state]_top") + var/mutable_appearance/TOP = mutable_appearance(icon, "[icon_state]_top") TOP.pixel_y = 2 * ingredients.len + 3 - add_overlay(I) + add_overlay(filling) add_overlay(TOP) return if(INGREDIENTS_FILL) cut_overlays() - I.color = filling_color + filling.color = filling_color if(INGREDIENTS_LINE) - I.pixel_y = rand(-8,3) - I.pixel_x = I.pixel_y + filling.pixel_x = filling.pixel_y = rand(-8,3) - add_overlay(I) + add_overlay(filling) /obj/item/weapon/reagent_containers/food/snacks/customizable/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/slice, reagents_per_slice) @@ -248,14 +247,14 @@ name = "[customname] sandwich" BS.reagents.trans_to(src, BS.reagents.total_volume) ingMax = ingredients.len //can't add more ingredients after that - var/image/TOP = new(icon, "[BS.icon_state]") + var/mutable_appearance/TOP = mutable_appearance(icon, "[BS.icon_state]") TOP.pixel_y = 2 * ingredients.len + 3 add_overlay(TOP) if(istype(BS, /obj/item/weapon/reagent_containers/food/snacks/breadslice/custom)) - var/image/O = new(icon, "[initial(BS.icon_state)]_filling") - O.color = BS.filling_color - O.pixel_y = 2 * ingredients.len + 3 - add_overlay(O) + var/mutable_appearance/filling = new(icon, "[initial(BS.icon_state)]_filling") + filling.color = BS.filling_color + filling.pixel_y = 2 * ingredients.len + 3 + add_overlay(filling) qdel(BS) return else @@ -313,7 +312,7 @@ /obj/item/weapon/reagent_containers/glass/bowl/update_icon() cut_overlays() if(reagents && reagents.total_volume) - var/image/filling = image('icons/obj/food/soupsalad.dmi', "fullbowl") + var/mutable_appearance/filling = mutable_appearance('icons/obj/food/soupsalad.dmi', "fullbowl") filling.color = mix_color_from_reagents(reagents.reagent_list) add_overlay(filling) else diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 96b8826971..d50c80567a 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -234,13 +234,13 @@ /obj/item/weapon/reagent_containers/food/snacks/proc/update_overlays(obj/item/weapon/reagent_containers/food/snacks/S) cut_overlays() - var/image/I = new(src.icon, "[initial(icon_state)]_filling") + var/mutable_appearance/filling = mutable_appearance(icon, "[initial(icon_state)]_filling") if(S.filling_color == "#FFFFFF") - I.color = pick("#FF0000","#0000FF","#008000","#FFFF00") + filling.color = pick("#FF0000","#0000FF","#008000","#FFFF00") else - I.color = S.filling_color + filling.color = S.filling_color - add_overlay(I) + add_overlay(filling) // initialize_cooked_food() is called when microwaving the food /obj/item/weapon/reagent_containers/food/snacks/proc/initialize_cooked_food(obj/item/weapon/reagent_containers/food/snacks/S, cooking_efficiency = 1) diff --git a/code/modules/food_and_drinks/food/snacks/meat.dm b/code/modules/food_and_drinks/food/snacks/meat.dm index 625a0bfd56..c1b5a55ac0 100644 --- a/code/modules/food_and_drinks/food/snacks/meat.dm +++ b/code/modules/food_and_drinks/food/snacks/meat.dm @@ -17,9 +17,9 @@ /obj/item/weapon/reagent_containers/food/snacks/meat/slab/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/meat/rawcutlet/slice, reagents_per_slice) ..() - var/image/I = new(icon, "rawcutlet_coloration") - I.color = filling_color - slice.add_overlay(I) + var/mutable_appearance/filling = mutable_appearance(icon, "rawcutlet_coloration") + filling.color = filling_color + slice.add_overlay(filling) slice.filling_color = filling_color slice.name = "raw [name] cutlet" slice.meat_type = name diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index 4a9001c68f..6ec7fd9a1e 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -383,13 +383,13 @@ icon = 'icons/obj/lollipop.dmi' icon_state = "lollipop_stick" list_reagents = list("nutriment" = 1, "vitamin" = 1, "iron" = 10, "sugar" = 5, "omnizine" = 2) //Honk - var/image/head + var/mutable_appearance/head var/headcolor = rgb(0, 0, 0) tastes = list("candy" = 1) /obj/item/weapon/reagent_containers/food/snacks/lollipop/New() ..() - head = image(icon = 'icons/obj/lollipop.dmi', icon_state = "lollipop_head") + head = mutable_appearance('icons/obj/lollipop.dmi', "lollipop_head") change_head_color(rgb(rand(0, 255), rand(0, 255), rand(0, 255))) /obj/item/weapon/reagent_containers/food/snacks/lollipop/proc/change_head_color(C) diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm index 68ccce9f2f..27016d0c20 100644 --- a/code/modules/food_and_drinks/food/snacks_pie.dm +++ b/code/modules/food_and_drinks/food/snacks_pie.dm @@ -33,7 +33,7 @@ if(ishuman(hit_atom)) var/mob/living/carbon/human/H = hit_atom - var/image/creamoverlay = image('icons/effects/creampie.dmi') + var/mutable_appearance/creamoverlay = mutable_appearance('icons/effects/creampie.dmi') if(H.dna.species.id == "lizard") creamoverlay.icon_state = "creampie_lizard" else diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index 13442c4032..a4d9a32d3d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -47,7 +47,7 @@ /obj/machinery/gibber/New() ..() - src.add_overlay(image('icons/obj/kitchen.dmi', "grjam")) + add_overlay("grjam") var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/gibber(null) B.apply_default_parts(src) @@ -72,15 +72,15 @@ /obj/machinery/gibber/update_icon() cut_overlays() if (dirty) - src.add_overlay(image('icons/obj/kitchen.dmi', "grbloody")) + add_overlay("grbloody") if(stat & (NOPOWER|BROKEN)) return if (!occupant) - src.add_overlay(image('icons/obj/kitchen.dmi', "grjam")) + add_overlay("grjam") else if (operating) - src.add_overlay(image('icons/obj/kitchen.dmi', "gruse")) + add_overlay("gruse") else - src.add_overlay(image('icons/obj/kitchen.dmi', "gridle")) + add_overlay("gridle") /obj/machinery/gibber/attack_paw(mob/user) return src.attack_hand(user) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index 1403fe02f0..d6f6c0f32e 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -59,21 +59,20 @@ icon_state = "pizzabox_open" if(pizza) icon_state = "pizzabox_messy" - var/image/pizzaimg = image(pizza.icon, icon_state = pizza.icon_state) - pizzaimg.pixel_y = -3 - add_overlay(pizzaimg) + var/mutable_appearance/pizza_overlay = mutable_appearance(pizza.icon, pizza.icon_state) + pizza_overlay.pixel_y = -3 + add_overlay(pizza_overlay) if(bomb) bomb.icon_state = "pizzabomb_[bomb_active ? "active" : "inactive"]" - var/image/bombimg = image(bomb.icon, icon_state = bomb.icon_state) - bombimg.pixel_y = 5 - add_overlay(bombimg) - else + var/mutable_appearance/bomb_overlay = mutable_appearance(bomb.icon, bomb.icon_state) + bomb_overlay.pixel_y = 5 + add_overlay(bomb_overlay) icon_state = "pizzabox[boxes.len + 1]" var/obj/item/pizzabox/box = boxes.len ? boxes[boxes.len] : src if(box.boxtag != "") - var/image/tagimg = image(icon, icon_state = "pizzabox_tag") - tagimg.pixel_y = boxes.len * 3 - add_overlay(tagimg) + var/mutable_appearance/tag_overlay = mutable_appearance(icon, "pizzabox_tag") + tag_overlay.pixel_y = boxes.len * 3 + add_overlay(tag_overlay) /obj/item/pizzabox/attack_self(mob/user) if(boxes.len > 0) diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index ebc9f84ae9..4e6f4c734e 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -234,31 +234,30 @@ if (cards.len == 1) var/datum/playingcard/P = cards[1] - var/image/I = new(src.icon, (concealed ? "card_back" : "[P.card_icon]") ) + var/mutable_appearance/card_overlay = mutable_appearance(icon, (concealed ? "card_back" : "[P.card_icon]") ) - I.pixel_x = I.pixel_x + (-5 + rand(10)) - I.pixel_y = I.pixel_y + (-5 + rand(10)) + card_overlay.pixel_x = card_overlay.pixel_x + (-5 + rand(10)) + card_overlay.pixel_y = card_overlay.pixel_y + (-5 + rand(10)) - add_overlay(I) + add_overlay(card_overlay) else - var/origin = -12 - var/offset = round(32 / cards.len) + var/origin = -12 + var/offset = round(32 / cards.len) - var/i = 0 - var/image/I + var/i = 0 + var/mutable_appearance/card_overlay for(var/datum/playingcard/P in cards) - I = new(src.icon, (concealed ? "card_back" : "[P.card_icon]") ) - I.pixel_x = origin + (offset * i) + card_overlay = mutable_appearance(icon, (concealed ? "card_back" : P.card_icon)) + card_overlay.pixel_x = origin + (offset * i) - add_overlay(I) + add_overlay(card_overlay) + i = i + 1 - i = i + 1 - - var/html = "" + var/html = "" for(var/datum/playingcard/card in cards) - html = html + "" + html = html + "" src.hi.updateContent("hand", html) diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm index 067162be8c..d418b40b81 100644 --- a/code/modules/holiday/easter.dm +++ b/code/modules/holiday/easter.dm @@ -73,8 +73,8 @@ /obj/item/weapon/storage/bag/easterbasket/proc/countEggs() cut_overlays() - add_overlay(image("icon" = icon, "icon_state" = "basket-grass", "layer" = -1)) - add_overlay(image("icon" = icon, "icon_state" = "basket-egg[contents.len <= 5 ? contents.len : 5]", "layer" = -1)) + add_overlay("basket-grass") + add_overlay("basket-egg[min(contents.len, 5)]") /obj/item/weapon/storage/bag/easterbasket/remove_from_storage(obj/item/W as obj, atom/new_location) ..() diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm index 442dd84aaf..85d623d1e9 100644 --- a/code/modules/hydroponics/beekeeping/honeycomb.dm +++ b/code/modules/hydroponics/beekeeping/honeycomb.dm @@ -21,13 +21,11 @@ /obj/item/weapon/reagent_containers/honeycomb/update_icon() cut_overlays() - var/image/honey + var/mutable_appearance/honey_overlay = mutable_appearance(icon, "honey") if(honey_color) - honey = image(icon = 'icons/obj/hydroponics/harvest.dmi', icon_state = "greyscale_honey") - honey.color = honey_color - else - honey = image(icon = 'icons/obj/hydroponics/harvest.dmi', icon_state = "honey") - add_overlay(honey) + honey_overlay.icon_state = "greyscale_honey" + honey_overlay.color = honey_color + add_overlay(honey_overlay) /obj/item/weapon/reagent_containers/honeycomb/proc/set_reagent(reagent) diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 2c995695d1..6a1c877b97 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -116,8 +116,9 @@ can_buckle = 1 buckle_requires_restraints = 1 to_chat(user, "You add a rod to [src].") - var/image/U = image(icon='icons/obj/hydroponics/equipment.dmi',icon_state="bonfire_rod",pixel_y=16) - underlays += U + var/mutable_appearance/rod_underlay = mutable_appearance('icons/obj/hydroponics/equipment.dmi', "bonfire_rod") + rod_underlay.pixel_y = 16 + underlays += rod_underlay if(W.is_hot()) StartBurning() diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index a034612092..b26a911b3a 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -259,7 +259,7 @@ if(istype(src, /obj/machinery/hydroponics/soil)) add_atom_colour(rgb(255, 175, 0), FIXED_COLOUR_PRIORITY) else - add_overlay(image('icons/obj/hydroponics/equipment.dmi', icon_state = "gaia_blessing")) + overlays += mutable_appearance('icons/obj/hydroponics/equipment.dmi', "gaia_blessing") set_light(3) update_icon_hoses() @@ -287,31 +287,30 @@ icon_state = "hoses-[n]" /obj/machinery/hydroponics/proc/update_icon_plant() - var/image/I + var/mutable_appearance/plant_overlay = mutable_appearance(myseed.growing_icon, layer = OBJ_LAYER + 0.01) if(dead) - I = image(icon = myseed.growing_icon, icon_state = myseed.icon_dead) + plant_overlay.icon_state = myseed.icon_dead else if(harvest) if(!myseed.icon_harvest) - I = image(icon = myseed.growing_icon, icon_state = "[myseed.icon_grow][myseed.growthstages]") + plant_overlay.icon_state = "[myseed.icon_grow][myseed.growthstages]" else - I = image(icon = myseed.growing_icon, icon_state = myseed.icon_harvest) + plant_overlay.icon_state = myseed.icon_harvest else var/t_growthstate = min(round((age / myseed.maturation) * myseed.growthstages), myseed.growthstages) - I = image(icon = myseed.growing_icon, icon_state = "[myseed.icon_grow][t_growthstate]") - I.layer = OBJ_LAYER + 0.01 - add_overlay(I) + plant_overlay.icon_state = "[myseed.icon_grow][t_growthstate]" + add_overlay(plant_overlay) /obj/machinery/hydroponics/proc/update_icon_lights() if(waterlevel <= 10) - add_overlay(image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lowwater3")) + add_overlay(mutable_appearance('icons/obj/hydroponics/equipment.dmi', "over_lowwater3")) if(nutrilevel <= 2) - add_overlay(image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lownutri3")) + add_overlay(mutable_appearance('icons/obj/hydroponics/equipment.dmi', "over_lownutri3")) if(plant_health <= (myseed.endurance / 2)) - add_overlay(image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lowhealth3")) + add_overlay(mutable_appearance('icons/obj/hydroponics/equipment.dmi', "over_lowhealth3")) if(weedlevel >= 5 || pestlevel >= 5 || toxic >= 40) - add_overlay(image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_alert3")) + add_overlay(mutable_appearance('icons/obj/hydroponics/equipment.dmi', "over_alert3")) if(harvest) - add_overlay(image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_harvest3")) + add_overlay(mutable_appearance('icons/obj/hydroponics/equipment.dmi', "over_harvest3")) /obj/machinery/hydroponics/examine(user) diff --git a/code/modules/hydroponics/sample.dm b/code/modules/hydroponics/sample.dm index a4ab2919be..52c2e1052f 100644 --- a/code/modules/hydroponics/sample.dm +++ b/code/modules/hydroponics/sample.dm @@ -8,9 +8,9 @@ /obj/item/seeds/sample/New() ..() if(sample_color) - var/image/I = image(icon, icon_state = "sample-filling") - I.color = sample_color - add_overlay(I) + var/mutable_appearance/filling = mutable_appearance(icon, "sample-filling") + filling.color = sample_color + add_overlay(filling) /obj/item/seeds/sample/get_analyzer_text() return " The DNA of this sample is damaged beyond recovery, it can't support life on its own.\n*---------*" diff --git a/code/modules/mining/equipment.dm b/code/modules/mining/equipment.dm index 02a752c2d7..36c3053143 100644 --- a/code/modules/mining/equipment.dm +++ b/code/modules/mining/equipment.dm @@ -513,7 +513,7 @@ var/charged = 1 var/charge_time = 16 var/atom/mark = null - var/marked_image = null + var/mutable_appearance/marked_underlay /obj/item/projectile/destabilizer name = "destabilizing force" @@ -530,15 +530,16 @@ if(hammer_synced.mark == target) return ..() if(isliving(target)) - if(hammer_synced.mark && hammer_synced.marked_image) - hammer_synced.mark.underlays -= hammer_synced.marked_image - hammer_synced.marked_image = null + if(hammer_synced.mark && hammer_synced.marked_underlay) + hammer_synced.mark.underlays -= hammer_synced.marked_underlay + hammer_synced.marked_underlay = null var/mob/living/L = target if(L.mob_size >= MOB_SIZE_LARGE) hammer_synced.mark = L - var/image/I = image('icons/effects/effects.dmi', loc = L, icon_state = "shield2",pixel_y = (-L.pixel_y),pixel_x = (-L.pixel_x)) - L.underlays += I - hammer_synced.marked_image = I + hammer_synced.marked_underlay = mutable_appearance('icons/effects/effects.dmi', "shield2") + hammer_synced.marked_underlay.pixel_x = -L.pixel_x + hammer_synced.marked_underlay.pixel_y = -L.pixel_y + L.underlays += hammer_synced.marked_underlay var/target_turf = get_turf(target) if(ismineralturf(target_turf)) var/turf/closed/mineral/M = target_turf @@ -570,9 +571,8 @@ new /obj/effect/overlay/temp/kinetic_blast(get_turf(L)) mark = 0 if(L.mob_size >= MOB_SIZE_LARGE) - L.underlays -= marked_image - qdel(marked_image) - marked_image = null + L.underlays -= marked_underlay + QDEL_NULL(marked_underlay) var/backstab_dir = get_dir(user, L) var/def_check = L.getarmor(type = "bomb") if((user.dir & backstab_dir) && (L.dir & backstab_dir)) diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index 463ee524f9..b8b1bcc6b9 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -69,9 +69,9 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) if(uses_left <= 0) user.drop_item(src) loc = A - var/image/balloon - var/image/balloon2 - var/image/balloon3 + var/mutable_appearance/balloon + var/mutable_appearance/balloon2 + var/mutable_appearance/balloon3 if(isliving(A)) var/mob/living/M = A M.Weaken(16) // Keep them from moving during the duration of the extraction @@ -82,12 +82,12 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) var/obj/effect/extraction_holder/holder_obj = new(A.loc) holder_obj.appearance = A.appearance A.loc = holder_obj - balloon2 = image('icons/obj/fulton_balloon.dmi',"fulton_expand") + balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand") balloon2.pixel_y = 10 balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM holder_obj.add_overlay(balloon2) sleep(4) - balloon = image('icons/obj/fulton_balloon.dmi',"fulton_balloon") + balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon") balloon.pixel_y = 10 balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM holder_obj.cut_overlay(balloon2) @@ -121,7 +121,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) sleep(10) animate(holder_obj, pixel_z = 10, time = 10) sleep(10) - balloon3 = image('icons/obj/fulton_balloon.dmi',"fulton_retract") + balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract") balloon3.pixel_y = 10 balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM holder_obj.cut_overlay(balloon) diff --git a/code/modules/mining/lavaland/ruins/gym.dm b/code/modules/mining/lavaland/ruins/gym.dm index c390851b1b..13e3e56f66 100644 --- a/code/modules/mining/lavaland/ruins/gym.dm +++ b/code/modules/mining/lavaland/ruins/gym.dm @@ -68,9 +68,8 @@ user.setDir(SOUTH) user.Stun(4) user.loc = src.loc - var/image/W = image('goon/icons/obj/fitness.dmi',"fitnessweight-w") - W.layer = WALL_OBJ_LAYER - add_overlay(W) + var/mutable_appearance/swole_overlay = mutable_appearance(icon, "fitnessweight-w", WALL_OBJ_LAYER) + add_overlay(swole_overlay) var/bragmessage = pick("pushing it to the limit","going into overdrive","burning with determination","rising up to the challenge", "getting strong now","getting ripped") user.visible_message("[user] is [bragmessage]!") var/reps = 0 @@ -93,5 +92,5 @@ animate(user, pixel_y = 0, time = 3) var/finishmessage = pick("You feel stronger!","You feel like you can take on the world!","You feel robust!","You feel indestructible!") icon_state = "fitnessweight" - cut_overlay(W) + cut_overlay(swole_overlay) to_chat(user, "[finishmessage]") \ No newline at end of file diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 98a6c3d46d..1e7f01d7a3 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -392,7 +392,7 @@ return if (CC.use(1)) - add_overlay(image('icons/obj/economy.dmi',"coin_string_overlay")) + add_overlay("coin_string_overlay") string_attached = 1 to_chat(user, "You attach a string to the coin.") else diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 7a77aab7cd..7946d67d10 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -37,10 +37,10 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) //These variables store hair data if the ghost originates from a species with head and/or facial hair. var/hair_style var/hair_color - var/image/hair_image + var/mutable_appearance/hair_overlay var/facial_hair_style var/facial_hair_color - var/image/facial_hair_image + var/mutable_appearance/facial_hair_overlay var/updatedir = 1 //Do we have to update our dir as the ghost moves around? var/lastsetting = null //Stores the last setting that ghost_others was set to, for a little more efficiency when we update ghost images. Null means no update is necessary @@ -161,13 +161,13 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) ghost_accs = client.prefs.ghost_accs ghost_others = client.prefs.ghost_others - if(hair_image) - cut_overlay(hair_image) - hair_image = null + if(hair_overlay) + cut_overlay(hair_overlay) + hair_overlay = null - if(facial_hair_image) - cut_overlay(facial_hair_image) - facial_hair_image = null + if(facial_hair_overlay) + cut_overlay(facial_hair_overlay) + facial_hair_overlay = null if(new_form) @@ -188,19 +188,19 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) if(facial_hair_style) S = GLOB.facial_hair_styles_list[facial_hair_style] if(S) - facial_hair_image = image("icon" = S.icon, "icon_state" = "[S.icon_state]", "layer" = -HAIR_LAYER) + facial_hair_overlay = mutable_appearance(S.icon, "[S.icon_state]", -HAIR_LAYER) if(facial_hair_color) - facial_hair_image.color = "#" + facial_hair_color - facial_hair_image.alpha = 200 - add_overlay(facial_hair_image) + facial_hair_overlay.color = "#" + facial_hair_color + facial_hair_overlay.alpha = 200 + add_overlay(facial_hair_overlay) if(hair_style) S = GLOB.hair_styles_list[hair_style] if(S) - hair_image = image("icon" = S.icon, "icon_state" = "[S.icon_state]", "layer" = -HAIR_LAYER) + hair_overlay = mutable_appearance(S.icon, "[S.icon_state]", -HAIR_LAYER) if(hair_color) - hair_image.color = "#" + hair_color - hair_image.alpha = 200 - add_overlay(hair_image) + hair_overlay.color = "#" + hair_color + hair_overlay.alpha = 200 + add_overlay(hair_overlay) /* * Increase the brightness of a color by calculating the average distance between the R, G and B values, diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm index 3512f6bcdc..8940220d3b 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm @@ -1,7 +1,7 @@ /mob/living/carbon/alien/humanoid/update_icons() cut_overlays() - for(var/image/I in overlays_standing) + for(var/I in overlays_standing) add_overlay(I) if(stat == DEAD) @@ -66,7 +66,7 @@ dmi_file = 'icons/mob/alienqueen.dmi' if(handcuffed) - overlays_standing[HANDCUFF_LAYER] = image(dmi_file,icon_state= cuff_icon, layer =-HANDCUFF_LAYER) + overlays_standing[HANDCUFF_LAYER] = mutable_appearance(dmi_file, cuff_icon, -HANDCUFF_LAYER) apply_overlay(HANDCUFF_LAYER) //Royals have bigger sprites, so inhand things must be handled differently. @@ -80,16 +80,14 @@ var/itm_state = l_hand.item_state if(!itm_state) itm_state = l_hand.icon_state - var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_l", "layer"=-HANDS_LAYER) - hands += I + hands += mutable_appearance(alt_inhands_file, "[itm_state][caste]_l", -HANDS_LAYER) var/obj/item/r_hand = get_item_for_held_index(2) if(r_hand) var/itm_state = r_hand.item_state if(!itm_state) itm_state = r_hand.icon_state - var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_r", "layer"=-HANDS_LAYER) - hands += I + hands += mutable_appearance(alt_inhands_file, "[itm_state][caste]_r", -HANDS_LAYER) overlays_standing[HANDS_LAYER] = hands apply_overlay(HANDS_LAYER) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/screen.dm b/code/modules/mob/living/carbon/alien/screen.dm index 700680486a..c3e0d88edd 100644 --- a/code/modules/mob/living/carbon/alien/screen.dm +++ b/code/modules/mob/living/carbon/alien/screen.dm @@ -18,7 +18,6 @@ return var/Qdir = get_dir(src, Q) var/Qdist = get_dist(src, Q) - image(icon,loc,icon_state,layer,dir) var/finder_icon = "finder_center" //Overlay showed when adjacent to or on top of the queen! switch(Qdist) if(2 to 7) @@ -27,7 +26,7 @@ finder_icon = "finder_med" if(21 to INFINITY) finder_icon = "finder_far" - var/image/finder_eye = image('icons/mob/screen_alien.dmi', icon_state = finder_icon, dir = Qdir) + var/image/finder_eye = image('icons/mob/screen_alien.dmi', finder_icon, dir = Qdir) hud_used.alien_queen_finder.add_overlay(finder_eye) /mob/living/carbon/alien/humanoid/royal/queen/findQueen() diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index 2823e56d00..68d94b4c04 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -81,7 +81,7 @@ var/mob/dead/observer/ghost = pick(candidates) - var/overlay = image('icons/mob/alien.dmi', loc = owner, icon_state = "burst_lie") + var/mutable_appearance/overlay = mutable_appearance('icons/mob/alien.dmi', "burst_lie") owner.add_overlay(overlay) var/atom/xeno_loc = get_turf(owner) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 29df56b669..97686940bd 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -751,7 +751,7 @@ ..() /mob/living/carbon/fakefire(var/fire_icon = "Generic_mob_burning") - var/image/new_fire_overlay = image("icon"='icons/mob/OnFire.dmi', "icon_state"= fire_icon, "layer"=-FIRE_LAYER) + var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/OnFire.dmi', fire_icon, -FIRE_LAYER) new_fire_overlay.appearance_flags = RESET_COLOR overlays_standing[FIRE_LAYER] = new_fire_overlay apply_overlay(FIRE_LAYER) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index be95d2e3d1..8b9899d067 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -732,8 +732,8 @@ /mob/living/carbon/human/wash_cream() //clean both to prevent a rare bug - cut_overlay(image('icons/effects/creampie.dmi', "creampie_lizard")) - cut_overlay(image('icons/effects/creampie.dmi', "creampie_human")) + cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_lizard")) + cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_human")) //Turns a mob black, flashes a skeleton overlay @@ -742,17 +742,19 @@ //Handle mutant parts if possible if(dna && dna.species) add_atom_colour("#000000", TEMPORARY_COLOUR_PRIORITY) - var/static/image/electrocution_skeleton_anim = image(icon = icon, icon_state = "electrocuted_base") - electrocution_skeleton_anim.appearance_flags = RESET_COLOR + var/static/mutable_appearance/electrocution_skeleton_anim + if(!electrocution_skeleton_anim) + electrocution_skeleton_anim = mutable_appearance(icon, "electrocuted_base") + electrocution_skeleton_anim.appearance_flags |= RESET_COLOR add_overlay(electrocution_skeleton_anim) addtimer(CALLBACK(src, .proc/end_electrocution_animation, electrocution_skeleton_anim), anim_duration) else //or just do a generic animation flick_overlay_view(image(icon,src,"electrocuted_generic",ABOVE_MOB_LAYER), src, anim_duration) -/mob/living/carbon/human/proc/end_electrocution_animation(image/I) +/mob/living/carbon/human/proc/end_electrocution_animation(mutable_appearance/MA) remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000") - cut_overlay(I) + cut_overlay(MA) /mob/living/carbon/human/canUseTopic(atom/movable/M, be_close = 0) if(incapacitated() || lying ) @@ -821,9 +823,9 @@ if(hal_screwyhud == SCREWYHUD_HEALTHY) icon_num = 0 if(icon_num) - hud_used.healthdoll.add_overlay(image('icons/mob/screen_gen.dmi',"[BP.body_zone][icon_num]")) + hud_used.healthdoll.add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[BP.body_zone][icon_num]")) for(var/t in get_missing_limbs()) //Missing limbs - hud_used.healthdoll.add_overlay(image('icons/mob/screen_gen.dmi',"[t]6")) + hud_used.healthdoll.add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[t]6")) else hud_used.healthdoll.icon_state = "healthdoll_DEAD" diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index ecca978880..71b607c928 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -229,22 +229,22 @@ fhair_state += dynamic_fhair_suffix fhair_file = 'icons/mob/facialhair_extensions.dmi' - var/image/img_facial = image("icon" = fhair_file, "icon_state" = fhair_state, "layer" = -HAIR_LAYER) + var/mutable_appearance/facial_overlay = mutable_appearance(fhair_file, fhair_state, -HAIR_LAYER) if(!forced_colour) if(hair_color) if(hair_color == "mutcolor") - img_facial.color = "#" + H.dna.features["mcolor"] + facial_overlay.color = "#" + H.dna.features["mcolor"] else - img_facial.color = "#" + hair_color + facial_overlay.color = "#" + hair_color else - img_facial.color = "#" + H.facial_hair_color + facial_overlay.color = "#" + H.facial_hair_color else - img_facial.color = forced_colour + facial_overlay.color = forced_colour - img_facial.alpha = hair_alpha + facial_overlay.alpha = hair_alpha - standing += img_facial + standing += facial_overlay if(H.head) var/obj/item/I = H.head @@ -262,9 +262,11 @@ hair_hidden = TRUE if(!hair_hidden || dynamic_hair_suffix) + var/mutable_appearance/hair_overlay = mutable_appearance(layer = -HAIR_LAYER) if(!hair_hidden && !H.getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain if(!(NOBLOOD in species_traits)) - standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained", "layer" = -HAIR_LAYER) + hair_overlay.icon = 'icons/mob/human_face.dmi' + hair_overlay.icon_state = "debrained" else if(H.hair_style && (HAIR in species_traits)) S = GLOB.hair_styles_list[H.hair_style] @@ -286,70 +288,70 @@ hair_state += dynamic_hair_suffix hair_file = 'icons/mob/hair_extensions.dmi' - var/image/img_hair = image("icon" = hair_file, "icon_state" = hair_state, "layer" = -HAIR_LAYER) + hair_overlay.icon = hair_file + hair_overlay.icon_state = hair_state if(!forced_colour) if(hair_color) if(hair_color == "mutcolor") - img_hair.color = "#" + H.dna.features["mcolor"] + hair_overlay.color = "#" + H.dna.features["mcolor"] else - img_hair.color = "#" + hair_color + hair_overlay.color = "#" + hair_color else - img_hair.color = "#" + H.hair_color + hair_overlay.color = "#" + H.hair_color else - img_hair.color = forced_colour - img_hair.alpha = hair_alpha - - img_hair.pixel_y += hair_y_offset - standing += img_hair + hair_overlay.color = forced_colour + hair_overlay.alpha = hair_alpha + hair_overlay.pixel_y += hair_y_offset + if(hair_overlay.icon) + standing += hair_overlay if(standing.len) - H.overlays_standing[HAIR_LAYER] = standing + H.overlays_standing[HAIR_LAYER] = standing H.apply_overlay(HAIR_LAYER) /datum/species/proc/handle_body(mob/living/carbon/human/H) H.remove_overlay(BODY_LAYER) - var/list/standing = list() + var/list/standing = list() var/obj/item/bodypart/head/HD = H.get_bodypart("head") if(!(H.disabilities & HUSK)) // lipstick if(H.lip_style && (LIPS in species_traits) && HD) - var/image/lips = image("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[H.lip_style]", "layer" = -BODY_LAYER) - lips.color = H.lip_color - lips.pixel_y += face_y_offset - standing += lips + var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[H.lip_style]", -BODY_LAYER) + lip_overlay.color = H.lip_color + lip_overlay.pixel_y += face_y_offset + standing += lip_overlay // eyes if((EYECOLOR in species_traits) && HD) - var/image/img_eyes = image("icon" = 'icons/mob/human_face.dmi', "icon_state" = "eyes", "layer" = -BODY_LAYER) - img_eyes.color = "#" + H.eye_color - img_eyes.pixel_y += face_y_offset - standing += img_eyes + var/mutable_appearance/eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER) + eye_overlay.color = "#" + H.eye_color + eye_overlay.pixel_y += face_y_offset + standing += eye_overlay //Underwear, Undershirts & Socks - /*This will be refactored at a later date if(H.underwear) var/datum/sprite_accessory/underwear/underwear = GLOB.underwear_list[H.underwear] if(underwear) - standing += image("icon"=underwear.icon, "icon_state"="[underwear.icon_state]", "layer"=-BODY_LAYER) + standing += mutable_appearance(underwear.icon, underwear.icon_state, -BODY_LAYER) if(H.undershirt) var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[H.undershirt] if(undershirt) if(H.dna.species.sexes && H.gender == FEMALE) - standing += wear_female_version("[undershirt.icon_state]", undershirt.icon, BODY_LAYER) + standing += wear_female_version(undershirt.icon_state, undershirt.icon, -BODY_LAYER) else - standing += image("icon"=undershirt.icon, "icon_state"="[undershirt.icon_state]", "layer"=-BODY_LAYER) + standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER) if(H.socks && H.get_num_legs() >= 2 && !(DIGITIGRADE in species_traits)) var/datum/sprite_accessory/socks/socks = GLOB.socks_list[H.socks] if(socks) - standing += image("icon"=socks.icon, "icon_state"="[socks.icon_state]", "layer"=-BODY_LAYER) - */ + standing += mutable_appearance(socks.icon, socks.icon_state, -BODY_LAYER) + if(standing.len) H.overlays_standing[BODY_LAYER] = standing @@ -486,8 +488,6 @@ var/g = (H.gender == FEMALE) ? "f" : "m" - var/image/I - for(var/layer in relevant_layers) var/layertext = mutant_bodyparts_layertext(layer) @@ -552,7 +552,9 @@ S = /datum/sprite_accessory/slimecoon_snout*/ if(!S || S.icon_state == "none") continue - + + var/mutable_appearance/accessory_overlay = mutable_appearance(S.icon, layer = -layer) + //A little rename so we don't have to use tail_lizard or tail_human when naming the sprites. if(bodypart == "tail_lizard" || bodypart == "tail_human" || bodypart == "mam_tail" || bodypart == "slimecoontail" || bodypart == "xenotail") bodypart = "tail" @@ -563,134 +565,136 @@ if(bodypart == "xenohead") bodypart = "xhead" - - var/icon_string - if(S.gender_specific) - icon_string = "[g]_[bodypart]_[S.icon_state]_[layertext]" + accessory_overlay.icon_state = "[g]_[bodypart]_[S.icon_state]_[layertext]" else - icon_string = "m_[bodypart]_[S.icon_state]_[layertext]" - - I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer) + accessory_overlay.icon_state = "m_[bodypart]_[S.icon_state]_[layertext]" if(S.center) - I = center_image(I,S.dimension_x,S.dimension_y) + accessory_overlay = center_image(accessory_overlay, S.dimension_x, S.dimension_y) if(!(H.disabilities & HUSK)) if(!forced_colour) switch(S.color_src) if(MUTCOLORS) if(fixed_mut_color) - I.color = "#[fixed_mut_color]" + accessory_overlay.color = "#[fixed_mut_color]" else - I.color = "#[H.dna.features["mcolor"]]" + accessory_overlay.color = "#[H.dna.features["mcolor"]]" if(MUTCOLORS2) if(fixed_mut_color2) - I.color = "#[fixed_mut_color2]" + accessory_overlay.color = "#[fixed_mut_color2]" else - I.color = "#[H.dna.features["mcolor2"]]" + accessory_overlay.color = "#[H.dna.features["mcolor2"]]" if(MUTCOLORS3) if(fixed_mut_color3) - I.color = "#[fixed_mut_color3]" + accessory_overlay.color = "#[fixed_mut_color3]" else - I.color = "#[H.dna.features["mcolor3"]]" - + accessory_overlay.color = "#[H.dna.features["mcolor3"]]" if(HAIR) if(hair_color == "mutcolor") - I.color = "#[H.dna.features["mcolor"]]" + accessory_overlay.color = "#[H.dna.features["mcolor"]]" else - I.color = "#[H.hair_color]" + accessory_overlay.color = "#[H.hair_color]" if(FACEHAIR) - I.color = "#[H.facial_hair_color]" + accessory_overlay.color = "#[H.facial_hair_color]" if(EYECOLOR) - I.color = "#[H.eye_color]" + accessory_overlay.color = "#[H.eye_color]" else - I.color = forced_colour - standing += I + accessory_overlay.color = forced_colour + standing += accessory_overlay if(S.hasinner) + var/mutable_appearance/inner_accessory_overlay = mutable_appearance(S.icon, layer = -layer) if(S.gender_specific) - icon_string = "[g]_[bodypart]inner_[S.icon_state]_[layertext]" + inner_accessory_overlay.icon_state = "[g]_[bodypart]inner_[S.icon_state]_[layertext]" else - icon_string = "m_[bodypart]inner_[S.icon_state]_[layertext]" - - I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer) + inner_accessory_overlay.icon_state = "m_[bodypart]inner_[S.icon_state]_[layertext]" if(S.center) - I = center_image(I,S.dimension_x,S.dimension_y) + inner_accessory_overlay = center_image(inner_accessory_overlay, S.dimension_x, S.dimension_y) - standing += I + standing += inner_accessory_overlay + if(S.extra) //apply the extra overlay, if there is one + var/mutable_appearance/extra_accessory_overlay = mutable_appearance(S.icon, layer = -layer) if(S.gender_specific) - icon_string = "[g]_[bodypart]_extra_[S.icon_state]_[layertext]" + extra_accessory_overlay.icon_state = "[g]_[bodypart]_extra_[S.icon_state]_[layertext]" else - icon_string = "m_[bodypart]_extra_[S.icon_state]_[layertext]" - - I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer) + extra_accessory_overlay.icon_state = "m_[bodypart]_extra_[S.icon_state]_[layertext]" if(S.center) - I = center_image(I,S.dimension_x,S.dimension_y) - - switch(S.extra_color_src) //change the color of the extra overlay - if(MUTCOLORS) - if(fixed_mut_color) - I.color = "#[fixed_mut_color]" - else - I.color = "#[H.dna.features["mcolor"]]" - if(MUTCOLORS2) - if(fixed_mut_color2) - I.color = "#[fixed_mut_color2]" - else - I.color = "#[H.dna.features["mcolor2"]]" - if(MUTCOLORS3) - if(fixed_mut_color3) - I.color = "#[fixed_mut_color3]" - else - I.color = "#[H.dna.features["mcolor3"]]" - if(HAIR) - if(hair_color == "mutcolor") - I.color = "#[H.dna.features["mcolor"]]" - else - I.color = "#[H.hair_color]" - if(FACEHAIR) - I.color = "#[H.facial_hair_color]" - if(EYECOLOR) - I.color = "#[H.eye_color]" - standing += I + extra_accessory_overlay.icon_state = center_image(extra_accessory_overlay, S.dimension_x, S.dimension_y) + + if(!forced_colour) + switch(S.extra_color_src) //change the color of the extra overlay + if(MUTCOLORS) + if(fixed_mut_color) + extra_accessory_overlay.color = "#[fixed_mut_color]" + else + extra_accessory_overlay.color = "#[H.dna.features["mcolor"]]" + if(MUTCOLORS2) + if(fixed_mut_color2) + extra_accessory_overlay.color = "#[fixed_mut_color2]" + else + extra_accessory_overlay.color = "#[H.dna.features["mcolor2"]]" + if(MUTCOLORS3) + if(fixed_mut_color3) + extra_accessory_overlay.color = "#[fixed_mut_color3]" + else + extra_accessory_overlay.color = "#[H.dna.features["mcolor3"]]" + if(HAIR) + if(hair_color == "mutcolor") + extra_accessory_overlay.color = "#[H.dna.features["mcolor"]]" + else + extra_accessory_overlay.color = "#[H.hair_color]" + if(FACEHAIR) + extra_accessory_overlay.color = "#[H.facial_hair_color]" + if(EYECOLOR) + extra_accessory_overlay.color = "#[H.eye_color]" + else + extra_accessory_overlay.color = forced_colour + standing += extra_accessory_overlay if(S.extra2) //apply the extra overlay, if there is one + var/mutable_appearance/extra2_accessory_overlay = mutable_appearance(S.icon, layer = -layer) if(S.gender_specific) - icon_string = "[g]_[bodypart]_extra2_[S.icon_state]_[layertext]" + extra2_accessory_overlay.icon_state = "[g]_[bodypart]_extra2_[S.icon_state]_[layertext]" else - icon_string = "m_[bodypart]_extra2_[S.icon_state]_[layertext]" - - I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer) + extra2_accessory_overlay.icon_state = "m_[bodypart]_extra2_[S.icon_state]_[layertext]" if(S.center) - I = center_image(I,S.dimension_x,S.dimension_y) - - switch(S.extra2_color_src) //change the color of the extra overlay - if(MUTCOLORS) - if(fixed_mut_color) - I.color = "#[fixed_mut_color]" - else - I.color = "#[H.dna.features["mcolor"]]" - if(MUTCOLORS2) - if(fixed_mut_color2) - I.color = "#[fixed_mut_color2]" - else - I.color = "#[H.dna.features["mcolor2"]]" - if(MUTCOLORS3) - if(fixed_mut_color3) - I.color = "#[fixed_mut_color3]" - else - I.color = "#[H.dna.features["mcolor3"]]" - if(HAIR) - if(hair_color == "mutcolor") - I.color = "#[H.dna.features["mcolor"]]" - else - I.color = "#[H.hair_color]" - standing += I + extra2_accessory_overlay.icon_state = center_image(extra2_accessory_overlay, S.dimension_x, S.dimension_y) + + if(!forced_colour) + switch(S.extra_color_src) //change the color of the extra overlay + if(MUTCOLORS) + if(fixed_mut_color) + extra2_accessory_overlay.color = "#[fixed_mut_color]" + else + extra2_accessory_overlay.color = "#[H.dna.features["mcolor"]]" + if(MUTCOLORS2) + if(fixed_mut_color2) + extra2_accessory_overlay.color = "#[fixed_mut_color2]" + else + extra2_accessory_overlay.color = "#[H.dna.features["mcolor2"]]" + if(MUTCOLORS3) + if(fixed_mut_color3) + extra2_accessory_overlay.color = "#[fixed_mut_color3]" + else + extra2_accessory_overlay.color = "#[H.dna.features["mcolor3"]]" + if(HAIR) + if(hair_color == "mutcolor") + extra2_accessory_overlay.color = "#[H.dna.features["mcolor"]]" + else + extra2_accessory_overlay.color = "#[H.hair_color]" + if(FACEHAIR) + extra2_accessory_overlay.color = "#[H.facial_hair_color]" + if(EYECOLOR) + extra2_accessory_overlay.color = "#[H.eye_color]" + else + extra2_accessory_overlay.color = forced_colour + standing += extra2_accessory_overlay H.overlays_standing[layer] = standing.Copy() standing = list() diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 307c0e685d..14cf9d2508 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -126,17 +126,17 @@ There are several things that need to be remembered: else if(U.adjusted == DIGITIGRADE_STYLE) t_color = "[t_color]_l" - var/image/standing + var/mutable_appearance/uniform_overlay if(dna && dna.species.sexes) var/G = (gender == FEMALE) ? "f" : "m" if(G == "f" && U.fitted != NO_FEMALE_UNIFORM) - standing = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = 'icons/mob/uniform.dmi', isinhands = FALSE, femaleuniform = U.fitted) + uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = 'icons/mob/uniform.dmi', isinhands = FALSE, femaleuniform = U.fitted) - if(!standing) - standing = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = 'icons/mob/uniform.dmi', isinhands = FALSE) + if(!uniform_overlay) + uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = 'icons/mob/uniform.dmi', isinhands = FALSE) - overlays_standing[UNIFORM_LAYER] = standing + overlays_standing[UNIFORM_LAYER] = uniform_overlay else if(!(dna && dna.species.nojumpsuit) && invdrop) // Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY @@ -161,8 +161,7 @@ There are several things that need to be remembered: update_observer_view(wear_id) //TODO: add an icon file for ID slot stuff, so it's less snowflakey - var/image/standing = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi') - overlays_standing[ID_LAYER] = standing + overlays_standing[ID_LAYER] = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi') apply_overlay(ID_LAYER) @@ -170,20 +169,20 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_inv_gloves() remove_overlay(GLOVES_LAYER) - if(get_num_arms() <2) - if(!gloves && blood_DNA) - if(has_left_hand()) - overlays_standing[GLOVES_LAYER] = image("icon"='icons/effects/blood.dmi', "icon_state"="bloodyhands_left", "layer"=-GLOVES_LAYER) - apply_overlay(GLOVES_LAYER) - else if(has_right_hand()) - overlays_standing[GLOVES_LAYER] = image("icon"='icons/effects/blood.dmi', "icon_state"="bloodyhands_right", "layer"=-GLOVES_LAYER) - apply_overlay(GLOVES_LAYER) - return - if(client && hud_used && hud_used.inv_slots[slot_gloves]) var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves] inv.update_icon() + if(!gloves && blood_DNA) + var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER) + if(get_num_arms() < 2) + if(has_left_hand()) + bloody_overlay.icon_state = "bloodyhands_left" + else if(has_right_hand()) + bloody_overlay.icon_state = "bloodyhands_right" + + overlays_standing[GLOVES_LAYER] = bloody_overlay + if(gloves) gloves.screen_loc = ui_gloves if(client && hud_used && hud_used.hud_shown) @@ -193,14 +192,7 @@ There are several things that need to be remembered: var/t_state = gloves.item_state if(!t_state) t_state = gloves.icon_state - - var/image/standing = gloves.build_worn_icon(state = t_state, default_layer = GLOVES_LAYER, default_icon_file = 'icons/mob/hands.dmi') - - overlays_standing[GLOVES_LAYER] = standing - - else - if(blood_DNA) - overlays_standing[GLOVES_LAYER] = image("icon"='icons/effects/blood.dmi', "icon_state"="bloodyhands", "layer"=-GLOVES_LAYER) + overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(state = t_state, default_layer = GLOVES_LAYER, default_icon_file = 'icons/mob/hands.dmi') apply_overlay(GLOVES_LAYER) @@ -223,8 +215,7 @@ There are several things that need to be remembered: update_observer_view(glasses,1) if(!(head && (head.flags_inv & HIDEEYES)) && !(wear_mask && (wear_mask.flags_inv & HIDEEYES))) - var/image/standing = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/eyes.dmi') - overlays_standing[GLASSES_LAYER] = standing + overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/eyes.dmi') apply_overlay(GLASSES_LAYER) @@ -246,8 +237,7 @@ There are several things that need to be remembered: client.screen += ears //add it to the client's screen update_observer_view(ears,1) - var/image/standing = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi') - overlays_standing[EARS_LAYER] = standing + overlays_standing[EARS_LAYER] = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi') apply_overlay(EARS_LAYER) @@ -268,8 +258,7 @@ There are several things that need to be remembered: if(hud_used.inventory_shown) //if the inventory is open client.screen += shoes //add it to client's screen update_observer_view(shoes,1) - var/image/standing = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = 'icons/mob/feet.dmi') - overlays_standing[SHOES_LAYER] = standing + overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = 'icons/mob/feet.dmi') apply_overlay(SHOES_LAYER) @@ -289,7 +278,7 @@ There are several things that need to be remembered: var/t_state = s_store.item_state if(!t_state) t_state = s_store.icon_state - overlays_standing[SUIT_STORE_LAYER] = image("icon"='icons/mob/belt_mirror.dmi', "icon_state"="[t_state]", "layer"=-SUIT_STORE_LAYER) + overlays_standing[SUIT_STORE_LAYER] = mutable_appearance('icons/mob/belt_mirror.dmi', t_state, -SUIT_STORE_LAYER) apply_overlay(SUIT_STORE_LAYER) @@ -315,8 +304,7 @@ There are several things that need to be remembered: if(!t_state) t_state = belt.icon_state - var/image/standing = belt.build_worn_icon(state = t_state, default_layer = BELT_LAYER, default_icon_file = 'icons/mob/belt.dmi') - overlays_standing[BELT_LAYER] = standing + overlays_standing[BELT_LAYER] = belt.build_worn_icon(state = t_state, default_layer = BELT_LAYER, default_icon_file = 'icons/mob/belt.dmi') apply_overlay(BELT_LAYER) @@ -337,8 +325,7 @@ There are several things that need to be remembered: client.screen += wear_suit update_observer_view(wear_suit,1) - var/image/standing = wear_suit.build_worn_icon(state = wear_suit.icon_state, default_layer = SUIT_LAYER, default_icon_file = 'icons/mob/suit.dmi') - overlays_standing[SUIT_LAYER] = standing + overlays_standing[SUIT_LAYER] = wear_suit.build_worn_icon(state = wear_suit.icon_state, default_layer = SUIT_LAYER, default_icon_file = 'icons/mob/suit.dmi') if(wear_suit.breakouttime) //suit is restraining drop_all_held_items() @@ -381,7 +368,7 @@ There are several things that need to be remembered: remove_overlay(LEGCUFF_LAYER) clear_alert("legcuffed") if(legcuffed) - overlays_standing[LEGCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="legcuff1", "layer"=-LEGCUFF_LAYER) + overlays_standing[LEGCUFF_LAYER] = mutable_appearance('icons/mob/mob.dmi', "legcuff1", -LEGCUFF_LAYER) apply_overlay(LEGCUFF_LAYER) throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = src.legcuffed) @@ -390,8 +377,7 @@ There are several things that need to be remembered: var/icon/female_clothing_icon = GLOB.female_clothing_icons[index] if(!female_clothing_icon) //Create standing/laying icons if they don't exist generate_female_clothing(index,t_color,icon,type) - var/standing = image("icon"=GLOB.female_clothing_icons["[t_color]"], "layer"=-layer) - return(standing) + return mutable_appearance(GLOB.female_clothing_icons[t_color], layer = -layer) /mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers) var/list/out = new @@ -440,12 +426,12 @@ There are several things that need to be remembered: /* -Does everything in relation to building the /image used in the mob's overlays list +Does everything in relation to building the /mutable_appearance used in the mob's overlays list covers: inhands and any other form of worn item - centering large images - layering images on custom layers - building images from custom icon files + centering large appearances + layering appearances on custom layers + building appearances from custom icon files By Remie Richards (yes I'm taking credit because this just removed 90% of the copypaste in update_icons()) @@ -480,13 +466,13 @@ generate/load female uniform sprites matching all previously decided variables if(!layer2use) layer2use = default_layer - var/image/standing + var/mutable_appearance/standing if(femaleuniform) standing = wear_female_version(state,file2use,layer2use,femaleuniform) if(!standing) - standing = image("icon"=file2use, "icon_state"=state,"layer"=-layer2use) + standing = mutable_appearance(file2use, state, -layer2use) - //Get the overlay images for this item when it's being worn + //Get the overlays for this item when it's being worn //eg: ammo counters, primed grenade flashes, etc. var/list/worn_overlays = worn_overlays(isinhands) if(worn_overlays && worn_overlays.len) diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm index 581bedcc2b..5074f5083f 100644 --- a/code/modules/mob/living/carbon/monkey/update_icons.dm +++ b/code/modules/mob/living/carbon/monkey/update_icons.dm @@ -34,8 +34,7 @@ hair_hidden = 1 if(!hair_hidden) if(!getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain - var/image/I = image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained", "layer" = -HAIR_LAYER) - overlays_standing[HAIR_LAYER] = I + overlays_standing[HAIR_LAYER] = mutable_appearance('icons/mob/human_face.dmi', "debrained", -HAIR_LAYER) apply_overlay(HAIR_LAYER) @@ -45,9 +44,9 @@ /mob/living/carbon/monkey/update_inv_legcuffed() remove_overlay(LEGCUFF_LAYER) if(legcuffed) - var/image/standing = image("icon"='icons/mob/mob.dmi', "icon_state"="legcuff1", "layer"=-LEGCUFF_LAYER) - standing.pixel_y = 8 - overlays_standing[LEGCUFF_LAYER] = standing + var/mutable_appearance/legcuff_overlay = mutable_appearance('icons/mob/mob.dmi', "legcuff1", -LEGCUFF_LAYER) + legcuff_overlay.pixel_y = 8 + overlays_standing[LEGCUFF_LAYER] = legcuff_overlay apply_overlay(LEGCUFF_LAYER) diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm index bd06c917a6..6cb0ef6f1b 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/update_icons.dm @@ -30,9 +30,8 @@ var/list/overlays_standing[TOTAL_LAYERS] /mob/living/carbon/proc/apply_overlay(cache_index) - var/I = overlays_standing[cache_index] - if(I) - add_overlay(I) + if((. = overlays_standing[cache_index])) + add_overlay(.) /mob/living/carbon/proc/remove_overlay(cache_index) var/I = overlays_standing[cache_index] @@ -79,8 +78,7 @@ if(get_held_index_of_item(I) % 2 == 0) icon_file = I.righthand_file - var/image/standing = I.build_worn_icon(state = t_state, default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE) - hands += standing + hands += I.build_worn_icon(state = t_state, default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE) overlays_standing[HANDS_LAYER] = hands apply_overlay(HANDS_LAYER) @@ -89,7 +87,7 @@ /mob/living/carbon/update_fire(var/fire_icon = "Generic_mob_burning") remove_overlay(FIRE_LAYER) if(on_fire) - var/image/new_fire_overlay = image("icon"='icons/mob/OnFire.dmi', "icon_state"= fire_icon, "layer"=-FIRE_LAYER) + var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/OnFire.dmi', fire_icon, -FIRE_LAYER) new_fire_overlay.appearance_flags = RESET_COLOR overlays_standing[FIRE_LAYER] = new_fire_overlay @@ -100,16 +98,16 @@ /mob/living/carbon/update_damage_overlays() remove_overlay(DAMAGE_LAYER) - var/image/standing = image("icon"='icons/mob/dam_mob.dmi', "icon_state"="blank", "layer"=-DAMAGE_LAYER) - overlays_standing[DAMAGE_LAYER] = standing + var/mutable_appearance/damage_overlay = mutable_appearance('icons/mob/dam_mob.dmi', "blank", -DAMAGE_LAYER) + overlays_standing[DAMAGE_LAYER] = damage_overlay for(var/X in bodyparts) var/obj/item/bodypart/BP = X if(BP.dmg_overlay_type) if(BP.brutestate) - standing.add_overlay("[BP.dmg_overlay_type]_[BP.body_zone]_[BP.brutestate]0") //we're adding icon_states of the base image as overlays + damage_overlay.add_overlay("[BP.dmg_overlay_type]_[BP.body_zone]_[BP.brutestate]0") //we're adding icon_states of the base image as overlays if(BP.burnstate) - standing.add_overlay("[BP.dmg_overlay_type]_[BP.body_zone]_0[BP.burnstate]") + damage_overlay.add_overlay("[BP.dmg_overlay_type]_[BP.body_zone]_0[BP.burnstate]") apply_overlay(DAMAGE_LAYER) @@ -126,8 +124,7 @@ if(wear_mask) if(!(head && (head.flags_inv & HIDEMASK))) - var/image/standing = wear_mask.build_worn_icon(state = wear_mask.icon_state, default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/mask.dmi') - overlays_standing[FACEMASK_LAYER] = standing + overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(state = wear_mask.icon_state, default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/mask.dmi') update_hud_wear_mask(wear_mask) apply_overlay(FACEMASK_LAYER) @@ -141,8 +138,7 @@ if(wear_neck) if(!(head && (head.flags_inv & HIDENECK))) - var/image/standing = wear_neck.build_worn_icon(state = wear_neck.icon_state, default_layer = NECK_LAYER, default_icon_file = 'icons/mob/neck.dmi') - overlays_standing[NECK_LAYER] = standing + overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(state = wear_neck.icon_state, default_layer = NECK_LAYER, default_icon_file = 'icons/mob/neck.dmi') update_hud_neck(wear_neck) apply_overlay(NECK_LAYER) @@ -155,8 +151,7 @@ inv.update_icon() if(back) - var/image/standing = back.build_worn_icon(state = back.icon_state, default_layer = BACK_LAYER, default_icon_file = 'icons/mob/back.dmi') - overlays_standing[BACK_LAYER] = standing + overlays_standing[BACK_LAYER] = back.build_worn_icon(state = back.icon_state, default_layer = BACK_LAYER, default_icon_file = 'icons/mob/back.dmi') update_hud_back(back) apply_overlay(BACK_LAYER) @@ -171,8 +166,7 @@ inv.update_icon() if(head) - var/image/standing = head.build_worn_icon(state = head.icon_state, default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/head.dmi') - overlays_standing[HEAD_LAYER] = standing + overlays_standing[HEAD_LAYER] = head.build_worn_icon(state = head.icon_state, default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/head.dmi') update_hud_head(head) apply_overlay(HEAD_LAYER) @@ -181,7 +175,7 @@ /mob/living/carbon/update_inv_handcuffed() remove_overlay(HANDCUFF_LAYER) if(handcuffed) - overlays_standing[HANDCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="handcuff1", "layer"=-HANDCUFF_LAYER) + overlays_standing[HANDCUFF_LAYER] = mutable_appearance('icons/mob/mob.dmi', "handcuff1", -HANDCUFF_LAYER) apply_overlay(HANDCUFF_LAYER) @@ -250,9 +244,7 @@ var/list/new_limbs = list() for(var/X in bodyparts) var/obj/item/bodypart/BP = X - var/image/temp = BP.get_limb_icon() - if(temp) - new_limbs += temp + new_limbs += BP.get_limb_icon() if(new_limbs.len) overlays_standing[BODYPARTS_LAYER] = new_limbs limb_icon_cache[icon_render_key] = new_limbs diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 0b45792be5..8187dde9aa 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -491,7 +491,7 @@ for(var/obj/effect/decal/cleanable/trail_holder/TH in src.loc) if((!(newdir in TH.existing_dirs) || trail_type == "trails_1" || trail_type == "trails_2") && TH.existing_dirs.len <= 16) //maximum amount of overlays is 16 (all light & heavy directions filled) TH.existing_dirs += newdir - TH.overlays.Add(image('icons/effects/blood.dmi',trail_type,dir = newdir)) + TH.add_overlay(image('icons/effects/blood.dmi', trail_type, dir = newdir)) TH.transfer_mob_blood_dna(src) /mob/living/carbon/human/makeTrail(turf/T) @@ -930,4 +930,4 @@ /mob/living/ConveyorMove() if((movement_type & FLYING) && !stat) return - ..() \ No newline at end of file + ..() diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 2a5823d91f..ba0b78e350 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -102,11 +102,11 @@ return /mob/living/silicon/robot/update_fire() - var/I = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Generic_mob_burning") + var/mutable_appearance/fire_overlay = mutable_appearance('icons/mob/OnFire.dmi', "Generic_mob_burning") if(on_fire) - add_overlay(I) + add_overlay(fire_overlay) else - cut_overlay(I) + cut_overlay(fire_overlay) /mob/living/silicon/robot/update_canmove() if(stat || buckled || lockcharge) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 67813f2b32..14b854d2a2 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -38,7 +38,7 @@ var/obj/item/module_active = null held_items = list(null, null, null) //we use held_items for the module holding, because that makes sense to do! - var/image/eye_lights + var/mutable_appearance/eye_lights var/mob/living/silicon/ai/connected_ai = null var/obj/item/weapon/stock_parts/cell/cell = null @@ -629,7 +629,7 @@ else add_overlay("ov-opencover -c") if(hat) - var/image/head_overlay = hat.build_worn_icon(state = hat.icon_state, default_layer = 20, default_icon_file = 'icons/mob/head.dmi') + var/mutable_appearance/head_overlay = hat.build_worn_icon(state = hat.icon_state, default_layer = 20, default_icon_file = 'icons/mob/head.dmi') head_overlay.pixel_y += hat_offset add_overlay(head_overlay) update_fire() diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 95e62a556d..25be049546 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -286,7 +286,7 @@ ..() spawn(5) if(skin) - add_overlay(image('icons/mob/aibots.dmi', "kit_skin_[skin]")) + add_overlay("kit_skin_[skin]") /obj/item/weapon/storage/firstaid/attackby(obj/item/bodypart/S, mob/user, params) @@ -333,7 +333,7 @@ build_step++ to_chat(user, "You add the health sensor to [src].") name = "First aid/robot arm/health analyzer assembly" - add_overlay(image('icons/mob/aibots.dmi', "na_scanner")) + add_overlay("na_scanner") if(1) if(isprox(W)) diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 59b66e652e..e11711f2bd 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -358,7 +358,7 @@ Auto Patrol[]"}, var/obj/item/weapon/ed209_assembly/Sa = new /obj/item/weapon/ed209_assembly(Tsec) Sa.build_step = 1 - Sa.add_overlay(image('icons/mob/aibots.dmi', "hs_hole")) + Sa.add_overlay("hs_hole") Sa.created_name = name new /obj/item/device/assembly/prox_sensor(Tsec) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 0a6633a54a..bcf4b86191 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -90,7 +90,7 @@ update_icon() if(skin) - add_overlay(image('icons/mob/aibots.dmi', "medskin_[skin]")) + add_overlay("medskin_[skin]") var/datum/job/doctor/J = new /datum/job/doctor access_card.access += J.get_access() diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index f09c0ba9ae..c6aa754b6e 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -407,7 +407,7 @@ cut_overlays() if(inventory_head) var/image/head_icon - var/datum/dog_fashion.DF = new inventory_head.dog_fashion(src) + var/datum/dog_fashion/DF = new inventory_head.dog_fashion(src) if(!DF.obj_icon_state) DF.obj_icon_state = inventory_head.icon_state @@ -417,17 +417,17 @@ DF.obj_color = inventory_head.color if(health <= 0) - head_icon = DF.get_image(dir = EAST) + head_icon = DF.get_overlay(dir = EAST) head_icon.pixel_y = -8 head_icon.transform = turn(head_icon.transform, 180) else - head_icon = DF.get_image() + head_icon = DF.get_overlay() add_overlay(head_icon) if(inventory_back) var/image/back_icon - var/datum/dog_fashion.DF = new inventory_back.dog_fashion(src) + var/datum/dog_fashion/DF = new inventory_back.dog_fashion(src) if(!DF.obj_icon_state) DF.obj_icon_state = inventory_back.icon_state @@ -437,18 +437,20 @@ DF.obj_color = inventory_back.color if(health <= 0) - back_icon = DF.get_image(dir = EAST) + back_icon = DF.get_overlay(dir = EAST) back_icon.pixel_y = -11 back_icon.transform = turn(back_icon.transform, 180) else - back_icon = DF.get_image() + back_icon = DF.get_overlay() add_overlay(back_icon) if(facehugger) + var/mutable_appearance/facehugger_overlay = mutable_appearance('icons/mob/mask.dmi') if(istype(src, /mob/living/simple_animal/pet/dog/corgi/puppy)) - add_overlay(image('icons/mob/mask.dmi',"facehugger_corgipuppy")) + facehugger_overlay.icon_state = "facehugger_corgipuppy" else - add_overlay(image('icons/mob/mask.dmi',"facehugger_corgi")) + facehugger_overlay.icon_state = "facehugger_corgi" + add_overlay(facehugger_overlay) if(pcollar) add_overlay(collar) add_overlay(pettag) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm index 7fb7caf8e9..259ca4327d 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm @@ -7,9 +7,8 @@ /mob/living/simple_animal/drone/proc/apply_overlay(cache_index) - var/I = drone_overlays[cache_index] - if(I) - add_overlay(I) + if((. = drone_overlays[cache_index])) + add_overlay(.) /mob/living/simple_animal/drone/proc/remove_overlay(cache_index) @@ -34,11 +33,11 @@ if(!r_state) r_state = r_hand.icon_state - var/image/r_hand_image = r_hand.build_worn_icon(state = r_state, default_layer = DRONE_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) + var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(state = r_state, default_layer = DRONE_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) if(y_shift) - r_hand_image.pixel_y += y_shift + r_hand_overlay.pixel_y += y_shift - hands_overlays += r_hand_image + hands_overlays += r_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) r_hand.layer = ABOVE_HUD_LAYER @@ -52,11 +51,11 @@ if(!l_state) l_state = l_hand.icon_state - var/image/l_hand_image = l_hand.build_worn_icon(state = l_state, default_layer = DRONE_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) + var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(state = l_state, default_layer = DRONE_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) if(y_shift) - l_hand_image.pixel_y += y_shift + l_hand_overlay.pixel_y += y_shift - hands_overlays += l_hand_image + hands_overlays += l_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) l_hand.layer = ABOVE_HUD_LAYER @@ -86,10 +85,10 @@ var/used_head_icon = 'icons/mob/head.dmi' if(istype(head, /obj/item/clothing/mask)) used_head_icon = 'icons/mob/mask.dmi' - var/image/head_overlay = head.build_worn_icon(state = head.icon_state, default_layer = DRONE_HEAD_LAYER, default_icon_file = used_head_icon) + var/mutable_appearance/head_overlay = head.build_worn_icon(state = head.icon_state, default_layer = DRONE_HEAD_LAYER, default_icon_file = used_head_icon) head_overlay.pixel_y += -15 - drone_overlays[DRONE_HEAD_LAYER] = head_overlay + drone_overlays[DRONE_HEAD_LAYER] = head_overlay apply_overlay(DRONE_HEAD_LAYER) diff --git a/code/modules/mob/living/simple_animal/friendly/pet.dm b/code/modules/mob/living/simple_animal/friendly/pet.dm index cb62ccb070..717a6f4e2d 100644 --- a/code/modules/mob/living/simple_animal/friendly/pet.dm +++ b/code/modules/mob/living/simple_animal/friendly/pet.dm @@ -2,8 +2,8 @@ icon = 'icons/mob/pets.dmi' mob_size = MOB_SIZE_SMALL var/obj/item/clothing/neck/petcollar/pcollar = null - var/image/collar = null - var/image/pettag = null + var/collar = "" + var/pettag = "" blood_volume = BLOOD_VOLUME_NORMAL devourable = TRUE @@ -11,8 +11,8 @@ if(istype(O, /obj/item/clothing/neck/petcollar) && !pcollar) var/obj/item/clothing/neck/petcollar/P = O pcollar = P - collar = image('icons/mob/pets.dmi', src, "[icon_state]collar") - pettag = image('icons/mob/pets.dmi', src, "[icon_state]tag") + collar = "[icon_state]collar" + pettag = "[icon_state]tag" regenerate_icons() to_chat(user, "You put the [P] around [src]'s neck.") if(P.tagname) @@ -47,5 +47,7 @@ /mob/living/simple_animal/pet/regenerate_icons() cut_overlays() - add_overlay(collar) - add_overlay(pettag) + if(collar) + add_overlay(collar) + if(pettag) + add_overlay(pettag) diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index e49e412047..be889a4183 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -260,9 +260,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians I.plane = ABOVE_HUD_PLANE /mob/living/simple_animal/hostile/guardian/proc/apply_overlay(cache_index) - var/I = guardian_overlays[cache_index] - if(I) - add_overlay(I) + if((. = guardian_overlays[cache_index])) + add_overlay(.) /mob/living/simple_animal/hostile/guardian/proc/remove_overlay(cache_index) var/I = guardian_overlays[cache_index] @@ -281,9 +280,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians if(!r_state) r_state = r_hand.icon_state - var/image/r_hand_image = r_hand.build_worn_icon(state = r_state, default_layer = GUARDIAN_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) - - hands_overlays += r_hand_image + hands_overlays += r_hand.build_worn_icon(state = r_state, default_layer = GUARDIAN_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) r_hand.layer = ABOVE_HUD_LAYER @@ -296,9 +293,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians if(!l_state) l_state = l_hand.icon_state - var/image/l_hand_image = l_hand.build_worn_icon(state = l_state, default_layer = GUARDIAN_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) - - hands_overlays += l_hand_image + hands_overlays += l_hand.build_worn_icon(state = l_state, default_layer = GUARDIAN_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) l_hand.layer = ABOVE_HUD_LAYER diff --git a/code/modules/mob/living/simple_animal/guardian/types/protector.dm b/code/modules/mob/living/simple_animal/guardian/types/protector.dm index 8021200421..eacf58410b 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/protector.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/protector.dm @@ -40,10 +40,10 @@ to_chat(src, "You switch to combat mode.") toggle = FALSE else - var/image/I = new('icons/effects/effects.dmi', "shield-grey") + var/mutable_appearance/shield_overlay = mutable_appearance('icons/effects/effects.dmi', "shield-grey") if(namedatum) - I.color = namedatum.colour - add_overlay(I) + shield_overlay.color = namedatum.colour + add_overlay(shield_overlay) melee_damage_lower = 2 melee_damage_upper = 2 speed = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 462bad0df1..67b3d451b9 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -71,9 +71,7 @@ /mob/living/simple_animal/hostile/bear/update_icons() ..() if(armored) - var/image/B = image(icon = 'icons/mob/animal.dmi', icon_state = "armor_bear") - if(B) - add_overlay(B) + add_overlay("armor_bear") /obj/item/bear_armor name = "pile of bear armor" diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index fbbd2c20c8..e7ab6e1b56 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -49,7 +49,6 @@ var/idle = 0 var/isqueen = FALSE var/icon_base = "bee" - var/static/list/bee_icons = list() /mob/living/simple_animal/hostile/poison/bees/Process_Spacemove(movement_dir = 0) @@ -91,24 +90,15 @@ if(beegent && beegent.color) col = beegent.color - var/image/base - if(!bee_icons["[icon_base]_base"]) - bee_icons["[icon_base]_base"] = image(icon = 'icons/mob/bees.dmi', icon_state = "[icon_base]_base") - base = bee_icons["[icon_base]_base"] - add_overlay(base) + add_overlay("[icon_base]_base") - var/image/greyscale - if(!bee_icons["[icon_base]_grey_[col]"]) - bee_icons["[icon_base]_grey_[col]"] = image(icon = 'icons/mob/bees.dmi', icon_state = "[icon_base]_grey") - greyscale = bee_icons["[icon_base]_grey_[col]"] - greyscale.color = col - add_overlay(greyscale) + var/static/mutable_appearance/greyscale_overlay + greyscale_overlay = greyscale_overlay || mutable_appearance('icons/mob/bees.dmi') + greyscale_overlay.icon_state = "[icon_base]_grey" + greyscale_overlay.color = col + add_overlay(greyscale_overlay) - var/image/wings - if(!bee_icons["[icon_base]_wings"]) - bee_icons["[icon_base]_wings"] = image(icon = 'icons/mob/bees.dmi', icon_state = "[icon_base]_wings") - wings = bee_icons["[icon_base]_wings"] - add_overlay(wings) + add_overlay("[icon_base]_wings") //We don't attack beekeepers/people dressed as bees//Todo: bee costume diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index 111ce9b9da..16df9e4c7a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -100,7 +100,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca var/mob/living/creator = null // the creator var/destroy_objects = 0 var/knockdown_people = 0 - var/image/googly_eyes = null + var/static/mutable_appearance/googly_eyes = mutable_appearance('icons/mob/mob.dmi', "googly_eyes") gold_core_spawnable = 0 /mob/living/simple_animal/hostile/mimic/copy/Initialize(mapload, obj/copy, mob/living/creator, destroy_original = 0) @@ -143,7 +143,6 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca icon_state = O.icon_state icon_living = icon_state copy_overlays(O) - googly_eyes = image('icons/mob/mob.dmi',"googly_eyes") add_overlay(googly_eyes) if(istype(O, /obj/structure) || istype(O, /obj/machinery)) health = (anchored * 50) + 50 @@ -178,11 +177,6 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca C.visible_message("\The [src] knocks down \the [C]!", \ "\The [src] knocks you down!") -/mob/living/simple_animal/hostile/mimic/copy/Aggro() - ..() - googly_eyes.setDir(get_dir(src,target)) - - /mob/living/simple_animal/hostile/mimic/copy/machine speak = list("HUMANS ARE IMPERFECT!", "YOU SHALL BE ASSIMILATED!", "YOU ARE HARMING YOURSELF", "You have been deemed hazardous. Will you comply?", \ "My logic is undeniable.", "One of us.", "FLESH IS WEAK", "THIS ISN'T WAR, THIS IS EXTERMINATION!") diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index 3149502c2c..d82a332027 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -29,12 +29,13 @@ unique_name = 1 speak_emote = list("squeaks") deathmessage = "fainted." + var/cap_color = "#ffffff" var/powerlevel = 0 //Tracks our general strength level gained from eating other shrooms var/bruised = 0 //If someone tries to cheat the system by attacking a shroom to lower its health, punish them so that it wont award levels to shrooms that eat it var/recovery_cooldown = 0 //So you can't repeatedly revive it during a fight var/faint_ticker = 0 //If we hit three, another mushroom's gonna eat us - var/image/cap_living = null //Where we store our cap icons so we dont generate them constantly to update our icon - var/image/cap_dead = null + var/static/mutable_appearance/cap_living //Where we store our cap icons so we dont generate them constantly to update our icon + var/static/mutable_appearance/cap_dead /mob/living/simple_animal/hostile/mushroom/examine(mob/user) ..() @@ -53,11 +54,10 @@ melee_damage_upper += rand(10,20) maxHealth += rand(40,60) move_to_delay = rand(3,11) - var/cap_color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) - cap_living = image('icons/mob/animal.dmi',icon_state = "mushroom_cap") - cap_dead = image('icons/mob/animal.dmi',icon_state = "mushroom_cap_dead") - cap_living.color = cap_color - cap_dead.color = cap_color + cap_living = cap_living || mutable_appearance(icon, "mushroom_cap") + cap_dead = cap_dead || mutable_appearance(icon, "mushroom_cap_dead") + + cap_color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) UpdateMushroomCap() health = maxHealth ..() @@ -101,6 +101,8 @@ /mob/living/simple_animal/hostile/mushroom/proc/UpdateMushroomCap() cut_overlays() + cap_living.color = cap_color + cap_dead.color = cap_color if(health == 0) add_overlay(cap_dead) else diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm index 9deb139497..f3b5866ec6 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm @@ -32,10 +32,10 @@ gold_core_spawnable = 0 //too spooky for science var/ghost_hair_style var/ghost_hair_color - var/image/ghost_hair = null + var/mutable_appearance/ghost_hair var/ghost_facial_hair_style var/ghost_facial_hair_color - var/image/ghost_facial_hair = null + var/mutable_appearance/ghost_facial_hair var/random = TRUE //if you want random names for ghosts or not /mob/living/simple_animal/hostile/retaliate/ghost/Initialize() @@ -48,19 +48,16 @@ name = "ghost of [pick(GLOB.first_names_male)] [pick(GLOB.last_names)]" if(1) name = "ghost of [pick(GLOB.first_names_female)] [pick(GLOB.last_names)]" - give_hair() /mob/living/simple_animal/hostile/retaliate/ghost/proc/give_hair() if(ghost_hair_style != null) - ghost_hair = image('icons/mob/human_face.dmi', "hair_[ghost_hair_style]") - ghost_hair.layer = -HAIR_LAYER + ghost_hair = mutable_appearance('icons/mob/human_face.dmi', "hair_[ghost_hair_style]", -HAIR_LAYER) ghost_hair.alpha = 200 ghost_hair.color = ghost_hair_color add_overlay(ghost_hair) if(ghost_facial_hair_style != null) - ghost_facial_hair = image('icons/mob/human_face.dmi', "facial_[ghost_facial_hair_style]") - ghost_facial_hair.layer = -HAIR_LAYER + ghost_facial_hair = mutable_appearance('icons/mob/human_face.dmi', "facial_[ghost_facial_hair_style]", -HAIR_LAYER) ghost_facial_hair.alpha = 200 ghost_facial_hair.color = ghost_facial_hair_color add_overlay(ghost_facial_hair) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index d9c6ed54c7..8971d33b28 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -118,7 +118,7 @@ if(stat != DEAD) icon_state = icon_text if(mood && !stat) - add_overlay(image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]")) + add_overlay("aslime-[mood]") else icon_state = icon_dead ..() diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 1d0b069301..729e924261 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -377,7 +377,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp /mob/proc/reagent_check(datum/reagent/R) // utilized in the species code return 1 -/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/image/alert_overlay = null, var/action = NOTIFY_JUMP, flashwindow = TRUE) //Easy notification of ghosts. +/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/mutable_appearance/alert_overlay = null, var/action = NOTIFY_JUMP, flashwindow = TRUE) //Easy notification of ghosts. if(SSatoms.initialized != INITIALIZATION_INNEW_REGULAR) //don't notify for objects created during a map load return for(var/mob/dead/observer/O in GLOB.player_list) @@ -396,17 +396,10 @@ It's fairly easy to fix if dealing with single letters but not so much with comp A.action = action A.target = source if(!alert_overlay) - var/old_layer = source.layer - var/old_plane = source.plane - source.layer = FLOAT_LAYER - source.plane = FLOAT_PLANE - A.add_overlay(source) - source.layer = old_layer - source.plane = old_plane - else - alert_overlay.layer = FLOAT_LAYER - alert_overlay.plane = FLOAT_PLANE - A.add_overlay(alert_overlay) + alert_overlay = new(src) + alert_overlay.layer = FLOAT_LAYER + alert_overlay.plane = FLOAT_PLANE + A.add_overlay(alert_overlay) /proc/item_heal_robotic(mob/living/carbon/human/H, mob/user, brute_heal, burn_heal) var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 72fe84de45..36e69828b2 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -336,12 +336,10 @@ return stamps += "" - var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') + var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[P.icon_state]") stampoverlay.pixel_x = rand(-2, 2) stampoverlay.pixel_y = rand(-3, 2) - stampoverlay.icon_state = "paper_[P.icon_state]" - LAZYADD(stamped, P.icon_state) add_overlay(stampoverlay) diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 00eeb13e4c..cf7c28d2ba 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -135,7 +135,7 @@ icon_state = "[initial(icon_state)]" cut_overlays() if(bin_pen) - add_overlay(image(icon=bin_pen.icon,icon_state=bin_pen.icon_state)) + add_overlay(mutable_appearance(bin_pen.icon, bin_pen.icon_state)) /obj/item/weapon/paper_bin/construction name = "construction paper bin" diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index e7742b4bc8..2514784bcb 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -44,8 +44,7 @@ var/list/stamped = internalPaper.stamped if(stamped) for(var/S in stamped) - var/image/stampoverlay = image('icons/obj/bureaucracy.dmi', "paperplane_[stamped]") - add_overlay(stampoverlay) + add_overlay("paperplane_[S]") /obj/item/weapon/paperplane/attack_self(mob/user) to_chat(user, "You unfold [src].") diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 3c8cc46732..4633285488 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -93,12 +93,6 @@ var/force_update = 0 var/update_state = -1 var/update_overlay = -1 - var/global/status_overlays = 0 - var/global/list/status_overlays_lock - var/global/list/status_overlays_charging - var/global/list/status_overlays_equipment - var/global/list/status_overlays_lighting - var/global/list/status_overlays_environ /obj/machinery/power/apc/connect_to_network() @@ -218,35 +212,6 @@ // update the APC icon to show the three base states // also add overlays for indicator lights /obj/machinery/power/apc/update_icon() - if (!status_overlays) - status_overlays = 1 - status_overlays_lock = new(2) - status_overlays_charging = new(3) - status_overlays_equipment = new(4) - status_overlays_lighting = new(4) - status_overlays_environ = new(4) - - status_overlays_lock[1] = image(icon, "apcox-0") // 0=blue 1=red - status_overlays_lock[2] = image(icon, "apcox-1") - - status_overlays_charging[1] = image(icon, "apco3-0") - status_overlays_charging[2] = image(icon, "apco3-1") - status_overlays_charging[3] = image(icon, "apco3-2") - - status_overlays_equipment[1] = image(icon, "apco0-0") - status_overlays_equipment[2] = image(icon, "apco0-1") - status_overlays_equipment[3] = image(icon, "apco0-2") - status_overlays_equipment[4] = image(icon, "apco0-3") - - status_overlays_lighting[1] = image(icon, "apco1-0") - status_overlays_lighting[2] = image(icon, "apco1-1") - status_overlays_lighting[3] = image(icon, "apco1-2") - status_overlays_lighting[4] = image(icon, "apco1-3") - - status_overlays_environ[1] = image(icon, "apco2-0") - status_overlays_environ[2] = image(icon, "apco2-1") - status_overlays_environ[3] = image(icon, "apco2-2") - status_overlays_environ[4] = image(icon, "apco2-3") var/update = check_updates() //returns 0 if no need to update icons. // 1 if we need to update the icon_state @@ -283,12 +248,12 @@ cut_overlays() if(!(stat & (BROKEN|MAINT)) && update_state & UPSTATE_ALLGOOD) var/list/O = list( - status_overlays_lock[locked+1], - status_overlays_charging[charging+1]) + "apcox-[locked]", + "apco3-[charging]") if(operating) - O += status_overlays_equipment[equipment+1] - O += status_overlays_lighting[lighting+1] - O += status_overlays_environ[environ+1] + O += "apco0-[equipment]" + O += "apco1-[lighting]" + O += "apco2-[environ]" add_overlay(O) // And now, seperately for cleanness, the lighting changing diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 01ba72287d..0d92f21494 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -49,13 +49,13 @@ /obj/item/weapon/stock_parts/cell/proc/updateicon() cut_overlays() if(grown_battery) - add_overlay(image('icons/obj/power.dmi', "grown_wires")) + add_overlay("grown_wires") if(charge < 0.01) return else if(charge/maxcharge >=0.995) - add_overlay(image('icons/obj/power.dmi', "cell-o2")) + add_overlay("cell-o2") else - add_overlay(image('icons/obj/power.dmi', "cell-o1")) + add_overlay("cell-o1") /obj/item/weapon/stock_parts/cell/proc/percent() // return % charge of cell return 100*charge/maxcharge diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index e9b351be49..dfbf3fe50b 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -64,9 +64,9 @@ cut_overlays() if(lastgenlev != 0) - add_overlay(image('icons/obj/power.dmi', "teg-op[lastgenlev]")) + add_overlay("teg-op[lastgenlev]") - add_overlay(image('icons/obj/power.dmi', "teg-oc[lastcirc]")) + add_overlay("teg-oc[lastcirc]") #define GENRATE 800 // generator output coefficient from Q diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index eb78c885aa..b75cf57acf 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -141,11 +141,11 @@ GLOBAL_LIST_EMPTY(rad_collectors) /obj/machinery/power/rad_collector/proc/update_icons() cut_overlays() if(loaded_tank) - add_overlay(image('icons/obj/singularity.dmi', "ptank")) + add_overlay("ptank") if(stat & (NOPOWER|BROKEN)) return if(active) - add_overlay(image('icons/obj/singularity.dmi', "on")) + add_overlay("on") /obj/machinery/power/rad_collector/proc/toggle_power() diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index dc54a3db4e..410181dede 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -33,7 +33,7 @@ var/area/A = get_area(src) if(A) - var/image/alert_overlay = image('icons/effects/effects.dmi', "ghostalertsie") + var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/effects.dmi', "ghostalertsie") notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.", source = src, alert_overlay = alert_overlay, action=NOTIFY_ATTACK) narsie_spawn_animation() diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index e03eaf944a..fdb4699ae5 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -38,9 +38,6 @@ var/obj/machinery/power/terminal/terminal = null - var/static/list/smesImageCache - - /obj/machinery/power/smes/examine(user) ..() if(!terminal) @@ -226,36 +223,20 @@ if(panel_open) return - if(!smesImageCache || !smesImageCache.len) - smesImageCache = list() - smesImageCache.len = 9 - - smesImageCache[SMES_CLEVEL_1] = image('icons/obj/power.dmi',"smes-og1") - smesImageCache[SMES_CLEVEL_2] = image('icons/obj/power.dmi',"smes-og2") - smesImageCache[SMES_CLEVEL_3] = image('icons/obj/power.dmi',"smes-og3") - smesImageCache[SMES_CLEVEL_4] = image('icons/obj/power.dmi',"smes-og4") - smesImageCache[SMES_CLEVEL_5] = image('icons/obj/power.dmi',"smes-og5") - - smesImageCache[SMES_OUTPUTTING] = image('icons/obj/power.dmi', "smes-op1") - smesImageCache[SMES_NOT_OUTPUTTING] = image('icons/obj/power.dmi',"smes-op0") - smesImageCache[SMES_INPUTTING] = image('icons/obj/power.dmi', "smes-oc1") - smesImageCache[SMES_INPUT_ATTEMPT] = image('icons/obj/power.dmi', "smes-oc0") - if(outputting) - add_overlay(smesImageCache[SMES_OUTPUTTING]) + add_overlay("smes-op1") else - add_overlay(smesImageCache[SMES_NOT_OUTPUTTING]) + add_overlay("smes-op0") if(inputting) - add_overlay(smesImageCache[SMES_INPUTTING]) + add_overlay("smes-oc1") else if(input_attempt) - add_overlay(smesImageCache[SMES_INPUT_ATTEMPT]) + add_overlay("smes-oc0") var/clevel = chargedisplay() if(clevel>0) - add_overlay(smesImageCache[clevel]) - return + add_overlay("smes-og[clevel]") /obj/machinery/power/smes/proc/chargedisplay() diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index e18e6781c2..47e04339d4 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -103,9 +103,9 @@ ..() cut_overlays() if(stat & BROKEN) - add_overlay(image('icons/obj/power.dmi', icon_state = "solar_panel-b", layer = FLY_LAYER)) + add_overlay(mutable_appearance(icon, "solar_panel-b", FLY_LAYER)) else - add_overlay(image('icons/obj/power.dmi', icon_state = "solar_panel", layer = FLY_LAYER)) + add_overlay(mutable_appearance(icon, "solar_panel", FLY_LAYER)) src.setDir(angle2dir(adir)) //calculates the fraction of the sunlight that the panel recieves @@ -345,7 +345,8 @@ else add_overlay(icon_screen) if(currentdir > -1) - add_overlay(image('icons/obj/computer.dmi', "solcon-o", FLY_LAYER, angle2dir(currentdir))) + setDir(angle2dir(currentdir)) + add_overlay(mutable_appearance(icon, "solcon-o", FLY_LAYER)) /obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index 4f194129bd..120dd0b46c 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -170,13 +170,13 @@ if(rpm>50000) - add_overlay(image('icons/obj/atmospherics/pipes/simple.dmi', "comp-o4", FLY_LAYER)) + add_overlay(mutable_appearance(icon, "comp-o4", FLY_LAYER)) else if(rpm>10000) - add_overlay(image('icons/obj/atmospherics/pipes/simple.dmi', "comp-o3", FLY_LAYER)) + add_overlay(mutable_appearance(icon, "comp-o3", FLY_LAYER)) else if(rpm>2000) - add_overlay(image('icons/obj/atmospherics/pipes/simple.dmi', "comp-o2", FLY_LAYER)) + add_overlay(mutable_appearance(icon, "comp-o2", FLY_LAYER)) else if(rpm>500) - add_overlay(image('icons/obj/atmospherics/pipes/simple.dmi', "comp-o1", FLY_LAYER)) + add_overlay(mutable_appearance(icon, "comp-o1", FLY_LAYER)) //TODO: DEFERRED // These are crucial to working of a turbine - the stats modify the power output. TurbGenQ modifies how much raw energy can you get from @@ -255,7 +255,7 @@ // If it works, put an overlay that it works! if(lastgen > 100) - add_overlay(image('icons/obj/atmospherics/pipes/simple.dmi', "turb-o", FLY_LAYER)) + add_overlay(mutable_appearance(icon, "turb-o", FLY_LAYER)) updateDialog() diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index c46a512c57..9e642b0cef 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -132,15 +132,20 @@ add_overlay("[icon_state]_empty") else if(!shaded_charge) + var/mutable_appearance/charge_overlay = mutable_appearance(icon, iconState) for(var/i = ratio, i >= 1, i--) - add_overlay(image(icon = icon, icon_state = iconState, pixel_x = ammo_x_offset * (i -1))) + charge_overlay.pixel_x = ammo_x_offset * (i - 1) + add_overlay(charge_overlay) else - add_overlay(image(icon = icon, icon_state = "[icon_state]_charge[ratio]")) + add_overlay("[icon_state]_charge[ratio]") if(gun_light && can_flashlight) var/iconF = "flight" if(gun_light.on) iconF = "flight_on" - add_overlay(image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset)) + var/mutable_appearance/flashlight_overlay = mutable_appearance(icon, iconF) + flashlight_overlay.pixel_x = flight_x_offset + flashlight_overlay.pixel_y = flight_y_offset + add_overlay(flashlight_overlay) if(itemState) itemState += "[ratio]" item_state = itemState diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 07450fc9b5..6a5dab12bf 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -136,7 +136,10 @@ var/iconF = "flight" if(gun_light.on) iconF = "flight_on" - add_overlay(image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset)) + var/mutable_appearance/flashlight_overlay = mutable_appearance(icon, iconF) + flashlight_overlay.pixel_x = flight_x_offset + flashlight_overlay.pixel_y = flight_y_offset + add_overlay(flashlight_overlay) //Casing /obj/item/ammo_casing/energy/kinetic diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index b4166d8070..f8989a2304 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -14,7 +14,7 @@ var/amount = 30 var/recharged = 0 var/recharge_delay = 5 - var/image/icon_beaker = null + var/mutable_appearance/beaker_overlay var/obj/item/weapon/reagent_containers/beaker = null var/list/dispensable_reagents = list( "hydrogen", @@ -184,10 +184,9 @@ beaker.loc = src to_chat(user, "You add \the [B] to the machine.") - if(!icon_beaker) - icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. - icon_beaker.pixel_x = rand(-10,5) - add_overlay(icon_beaker) + beaker_overlay = beaker_overlay || mutable_appearance(icon, "disp_beaker") + beaker_overlay.pixel_x = rand(-10, 5)//randomize beaker overlay position. + add_overlay(beaker_overlay) else if(user.a_intent != INTENT_HARM && !istype(I, /obj/item/weapon/card/emag)) to_chat(user, "You can't load \the [I] into the machine!") else diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index cb06dc29ee..5eb034d604 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -15,7 +15,7 @@ else Wall.thermite = Wall.thermite+(reac_volume*10) Wall.overlays = list() - Wall.add_overlay(image('icons/effects/effects.dmi',"thermite")) + Wall.add_overlay(mutable_appearance('icons/effects/effects.dmi', "thermite")) /datum/reagent/thermite/on_mob_life(mob/living/M) M.adjustFireLoss(1, 0) diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index 01f39db4d3..fc08ebdbe8 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -21,7 +21,7 @@ /obj/item/weapon/reagent_containers/glass/bottle/update_icon() cut_overlays() if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]-10") + var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[icon_state]-10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 01b1d4dc28..05c58f5db8 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -91,6 +91,6 @@ /obj/item/weapon/reagent_containers/dropper/update_icon() cut_overlays() if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "dropper") + var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "dropper") filling.color = mix_color_from_reagents(reagents.reagent_list) add_overlay(filling) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index d9f21b5c26..10b584cdfb 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -133,7 +133,7 @@ cut_overlays() if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]10") + var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[icon_state]10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 77cbb10c8b..eea1fe7a2b 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -167,10 +167,9 @@ item_state = "syringe_[rounded_vol]" if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "syringe10") - filling.icon_state = "syringe[rounded_vol]" - filling.color = mix_color_from_reagents(reagents.reagent_list) - add_overlay(filling) + var/image/filling_overlay = mutable_appearance('icons/obj/reagentfillings.dmi', "syringe[rounded_vol]") + filling_overlay.color = mix_color_from_reagents(reagents.reagent_list) + add_overlay(filling_overlay) /obj/item/weapon/reagent_containers/syringe/epinephrine name = "syringe (epinephrine)" diff --git a/code/modules/recycling/disposal-unit.dm b/code/modules/recycling/disposal-unit.dm index 7cc890c1f6..9b1d5e649f 100644 --- a/code/modules/recycling/disposal-unit.dm +++ b/code/modules/recycling/disposal-unit.dm @@ -364,7 +364,7 @@ //flush handle if(flush) - add_overlay(image('icons/obj/atmospherics/pipes/disposal.dmi', "dispover-handle")) + add_overlay("dispover-handle") //only handle is shown if no power if(stat & NOPOWER || panel_open) @@ -372,13 +372,13 @@ //check for items in disposal - occupied light if(contents.len > 0) - add_overlay(image('icons/obj/atmospherics/pipes/disposal.dmi', "dispover-full")) + add_overlay("dispover-full") //charging and ready light if(pressure_charging) - add_overlay(image('icons/obj/atmospherics/pipes/disposal.dmi', "dispover-charge")) + add_overlay("dispover-charge") else if(full_pressure) - add_overlay(image('icons/obj/atmospherics/pipes/disposal.dmi', "dispover-ready")) + add_overlay("dispover-ready") //timed process //charge the gas reservoir and perform flush if ready diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index d4b19a77b1..f0d563b1ff 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -4,7 +4,7 @@ GLOBAL_LIST_INIT(message_servers, list()) var/recipient = "Unspecified" //name of the person var/sender = "Unspecified" //name of the sender var/message = "Blank" //transferred message - var/image/photo = null //Attached photo + var/icon/photo //Attached photo /datum/data_pda_msg/New(var/param_rec = "",var/param_sender = "",var/param_message = "",var/param_photo=null) diff --git a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm index 6d18ce98f7..2938f9263c 100644 --- a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm +++ b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm @@ -47,7 +47,7 @@ to_chat(M, "Discordant whispers flood your mind in a thousand voices. Each one speaks your name, over and over. Something horrible has come.") M << 'sound/creatures/legion_spawn.ogg' flash_color(M, flash_color = "#FF0000", flash_time = 50) - var/image/door_overlay = image('icons/effects/effects.dmi', "legiondoor") + var/mutable_appearance/door_overlay = mutable_appearance('icons/effects/effects.dmi', "legiondoor") notify_ghosts("Legion has been summoned in the [get_area(src)]!", source = src, alert_overlay = door_overlay, action = NOTIFY_JUMP) is_anyone_home = FALSE new/mob/living/simple_animal/hostile/megafauna/legion(get_step(src.loc, SOUTH)) diff --git a/code/modules/shuttle/manipulator.dm b/code/modules/shuttle/manipulator.dm index bb2f401cdb..594a6855da 100644 --- a/code/modules/shuttle/manipulator.dm +++ b/code/modules/shuttle/manipulator.dm @@ -26,9 +26,9 @@ /obj/machinery/shuttle_manipulator/update_icon() cut_overlays() - var/image/hologram_projection = image(icon, "hologram_on") + var/mutable_appearance/hologram_projection = mutable_appearance(icon, "hologram_on") hologram_projection.pixel_y = 22 - var/image/hologram_ship = image(icon, "hologram_whiteship") + var/mutable_appearance/hologram_ship = mutable_appearance(icon, "hologram_whiteship") hologram_ship.pixel_y = 27 add_overlay(hologram_projection) add_overlay(hologram_ship) diff --git a/code/modules/spells/spell_types/lightning.dm b/code/modules/spells/spell_types/lightning.dm index 4f469b61b2..3a84f73ef9 100644 --- a/code/modules/spells/spell_types/lightning.dm +++ b/code/modules/spells/spell_types/lightning.dm @@ -11,7 +11,7 @@ selection_type = "view" random_target = 1 var/ready = 0 - var/image/halo = null + var/static/mutable_appearance/halo var/sound/Snd // so far only way i can think of to stop a sound, thank MSO for the idea. action_icon_state = "lightning" @@ -25,7 +25,7 @@ ready = 1 to_chat(user, "You start gathering the power.") Snd = new/sound('sound/magic/lightning_chargeup.ogg',channel = 7) - halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER) + halo = halo || mutable_appearance('icons/effects/effects.dmi', "electricity", EFFECTS_LAYER) user.add_overlay(halo) playsound(get_turf(user), Snd, 50, 0) if(do_mob(user,user,100,1)) @@ -38,8 +38,7 @@ /obj/effect/proc_holder/spell/targeted/tesla/proc/Reset(mob/user = usr) ready = 0 - if(halo) - user.cut_overlay(halo) + user.cut_overlay(halo) /obj/effect/proc_holder/spell/targeted/tesla/revert_cast(mob/user = usr, message = 1) if(message) diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm index 0d4200d49e..53a7198302 100644 --- a/code/modules/station_goals/bsa.dm +++ b/code/modules/station_goals/bsa.dm @@ -127,7 +127,7 @@ icon = 'icons/obj/lavaland/cannon.dmi' icon_state = "orbital_cannon1" unsecuring_tool = null - var/static/image/top_layer = null + var/static/mutable_appearance/top_layer var/ex_power = 3 var/power_used_per_shot = 2000000 //enough to kil standard apc - todo : make this use wires instead and scale explosion power with it var/ready @@ -163,17 +163,16 @@ /obj/machinery/bsa/full/New(loc,cannon_direction = WEST) ..() + top_layer = top_layer || mutable_appearance(icon, layer = ABOVE_MOB_LAYER) switch(cannon_direction) if(WEST) dir = WEST pixel_x = -192 - top_layer = image("icons/obj/lavaland/orbital_cannon.dmi", "top_west") - top_layer.layer = ABOVE_MOB_LAYER + top_layer.icon_state = "top_west" icon_state = "cannon_west" if(EAST) dir = EAST - top_layer = image("icons/obj/lavaland/orbital_cannon.dmi", "top_east") - top_layer.layer = ABOVE_MOB_LAYER + top_layer.icon_state = "top_east" icon_state = "cannon_east" add_overlay(top_layer) reload() diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index 56d35be23b..d93fc658dd 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -284,79 +284,66 @@ /obj/item/bodypart/proc/get_limb_icon(dropped) icon_state = "" //to erase the default sprite, we're building the visual aspects of the bodypart through overlays alone. - var/list/standing = list() + . = list() - var/image_dir + var/image_dir = 0 if(dropped) image_dir = SOUTH if(dmg_overlay_type) if(brutestate) - standing += image("icon"='icons/mob/dam_mob.dmi', "icon_state"="[dmg_overlay_type]_[body_zone]_[brutestate]0", "layer"=-DAMAGE_LAYER, "dir"=image_dir) + . += image('icons/mob/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_[brutestate]0", -DAMAGE_LAYER, image_dir) if(burnstate) - standing += image("icon"='icons/mob/dam_mob.dmi', "icon_state"="[dmg_overlay_type]_[body_zone]_0[burnstate]", "layer"=-DAMAGE_LAYER, "dir"=image_dir) + . += image('icons/mob/dam_mob.dmi', "[dmg_overlay_type]_[body_zone]_0[burnstate]", -DAMAGE_LAYER, image_dir) + var/image/limb = image(layer = -BODYPARTS_LAYER, dir = image_dir) + . += limb if(animal_origin) if(status == BODYPART_ORGANIC) + limb.icon = 'icons/mob/animal_parts.dmi' if(species_id == "husk") - standing += image("icon"='icons/mob/animal_parts.dmi', "icon_state"="[animal_origin]_husk_[body_zone]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + limb.icon_state = "[animal_origin]_husk_[body_zone]" else - standing += image("icon"='icons/mob/animal_parts.dmi', "icon_state"="[animal_origin]_[body_zone]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + limb.icon_state = "[animal_origin]_[body_zone]" else - standing += image("icon"='icons/mob/augments.dmi', "icon_state"="[animal_origin]_[body_zone]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) - return standing + limb.icon = 'icons/mob/augments.dmi' + limb.icon_state = "[animal_origin]_[body_zone]" + return var/icon_gender = (body_gender == FEMALE) ? "f" : "m" //gender of the icon, if applicable if((body_zone != "head" && body_zone != "chest")) should_draw_gender = FALSE - var/image/I - if(status == BODYPART_ORGANIC) if(should_draw_greyscale) + limb.icon = 'icons/mob/human_parts_greyscale.dmi' if(should_draw_gender) - I = image("icon"='icons/mob/human_parts_greyscale.dmi', "icon_state"="[species_id]_[body_zone]_[icon_gender]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + limb.icon_state = "[species_id]_[body_zone]_[icon_gender]" else if(use_digitigrade) - I = image("icon"='icons/mob/human_parts_greyscale.dmi', "icon_state"="digitigrade_[use_digitigrade]_[body_zone]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + limb.icon_state = "digitigrade_[use_digitigrade]_[body_zone]" else - I = image("icon"='icons/mob/human_parts_greyscale.dmi', "icon_state"="[species_id]_[body_zone]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + limb.icon_state = "[species_id]_[body_zone]" else + limb.icon = 'icons/mob/human_parts.dmi' if(should_draw_gender) - I = image("icon"='icons/mob/human_parts.dmi', "icon_state"="[species_id]_[body_zone]_[icon_gender]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + limb.icon_state = "[species_id]_[body_zone]_[icon_gender]" else - I = image("icon"='icons/mob/human_parts.dmi', "icon_state"="[species_id]_[body_zone]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + limb.icon_state = "[species_id]_[body_zone]" + else + limb.icon = icon if(should_draw_gender) - I = image("icon"= icon, "icon_state"="[body_zone]_[icon_gender]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) + limb.icon_state = "[body_zone]_[icon_gender]" else - I = image("icon"= icon, "icon_state"="[body_zone]", "layer"=-BODYPARTS_LAYER, "dir"=image_dir) - standing += I - return standing - - - if(!should_draw_greyscale) - standing += I - return standing - - //Greyscale Colouring - var/draw_color - - if(skin_tone) //Limb has skin color variable defined, use it - draw_color = skintone2hex(skin_tone) - if(species_color) - draw_color = species_color - if(mutation_color) - draw_color = mutation_color - - if(draw_color) - I.color = "#[draw_color]" - //End Greyscale Colouring - standing += I - - return standing + limb.icon_state = "[body_zone]" + return + if(should_draw_greyscale) + var/draw_color = mutation_color || species_color || (skin_tone && skintone2hex(skin_tone)) + if(draw_color) + limb.color = "#[draw_color]" /obj/item/bodypart/deconstruct(disassembled = TRUE) drop_organs() diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 6417ade819..909f83e4d7 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -119,7 +119,7 @@ /obj/item/bodypart/head/get_limb_icon(dropped) cut_overlays() - var/list/standing = ..() + . = ..() if(dropped) //certain overlays only appear when the limb is being detached from its owner. var/datum/sprite_accessory/S @@ -128,45 +128,48 @@ if(facial_hair_style) S = GLOB.facial_hair_styles_list[facial_hair_style] if(S) - var/image/img_facial = image("icon" = S.icon, "icon_state" = "[S.icon_state]", "layer" = -HAIR_LAYER, "dir"=SOUTH) - img_facial.color = "#" + facial_hair_color - img_facial.alpha = hair_alpha - standing += img_facial + var/image/facial_overlay = image(S.icon, "[S.icon_state]", -HAIR_LAYER, SOUTH) + facial_overlay.color = "#" + facial_hair_color + facial_overlay.alpha = hair_alpha + . += facial_overlay + var/image/hair_overlay = image(layer = -HAIR_LAYER, dir = SOUTH) + . += hair_overlay //Applies the debrained overlay if there is no brain if(!brain) if(animal_origin == ALIEN_BODYPART) - standing += image("icon"='icons/mob/animal_parts.dmi', "icon_state" = "debrained_alien", "layer" = -HAIR_LAYER, "dir"=SOUTH) + hair_overlay.icon = 'icons/mob/animal_parts.dmi' + hair_overlay.icon_state = "debrained_alien" else if(animal_origin == LARVA_BODYPART) - standing += image("icon"='icons/mob/animal_parts.dmi', "icon_state" = "debrained_larva", "layer" = -HAIR_LAYER, "dir"=SOUTH) + hair_overlay.icon = 'icons/mob/animal_parts.dmi' + hair_overlay.icon_state = "debrained_larva" else if(!(NOBLOOD in species_flags_list)) - standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained", "layer" = -HAIR_LAYER, "dir"=SOUTH) + hair_overlay.icon = 'icons/mob/human_face.dmi' + hair_overlay.icon_state = "debrained" else if(hair_style) S = GLOB.hair_styles_list[hair_style] if(S) - var/image/img_hair = image("icon" = S.icon, "icon_state" = "[S.icon_state]", "layer" = -HAIR_LAYER, "dir"=SOUTH) - img_hair.color = "#" + hair_color - img_hair.alpha = hair_alpha - standing += img_hair + hair_overlay.icon = icon + hair_overlay.icon_state = "[S.icon_state]" + hair_overlay.color = "#" + hair_color + hair_overlay.alpha = hair_alpha // lipstick if(lip_style) - var/image/lips = image("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[lip_style]", "layer" = -BODY_LAYER, "dir"=SOUTH) - lips.color = lip_color - standing += lips + var/image/lips_overlay = image('icons/mob/human_face.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH) + lips_overlay.color = lip_color + . += lips_overlay // eyes + var/image/eyes_overlay = image('icons/mob/human_face.dmi', "eyes", -BODY_LAYER, SOUTH) + . += eyes_overlay if(!eyes) - standing += image("icon"='icons/mob/human_face.dmi', "icon_state" = "eyes_missing", "layer" = -BODY_LAYER, "dir"=SOUTH) + eyes_overlay.icon_state = "eyes_missing" else if(eyes.eye_color) - var/image/img_eyes = image("icon" = 'icons/mob/human_face.dmi', "icon_state" = "eyes", "layer" = -BODY_LAYER, "dir"=SOUTH) - img_eyes.color = "#" + eyes.eye_color - standing += img_eyes - - return standing + eyes_overlay.color = "#" + eyes.eye_color /obj/item/bodypart/head/monkey icon = 'icons/mob/animal_parts.dmi' diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 85a98b09e6..7b4f98693c 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -11,7 +11,7 @@ if(iscarbon(M)) src.Insert(M) if(implant_overlay) - var/image/overlay = new /image(icon, implant_overlay) + var/mutable_appearance/overlay = mutable_appearance(icon, implant_overlay) overlay.color = implant_color add_overlay(overlay) return ..() diff --git a/code/modules/vehicles/atv.dm b/code/modules/vehicles/atv.dm index 6afd401b75..5f663b85f8 100644 --- a/code/modules/vehicles/atv.dm +++ b/code/modules/vehicles/atv.dm @@ -3,7 +3,7 @@ name = "all-terrain vehicle" desc = "An all-terrain vehicle built for traversing rough terrain with ease. One of the few old-earth technologies that are still relevant on most planet-bound outposts." icon_state = "atv" - var/static/image/atvcover = null + var/static/mutable_appearance/atvcover /obj/vehicle/atv/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1) . = ..() @@ -11,9 +11,7 @@ /obj/vehicle/atv/New() ..() - if(!atvcover) - atvcover = image("icons/obj/vehicles.dmi", "atvcover") - atvcover.layer = ABOVE_MOB_LAYER + atvcover = atvcover || mutable_appearance(icon, "atvcover", ABOVE_MOB_LAYER) /obj/vehicle/atv/post_buckle_mob(mob/living/M) diff --git a/code/modules/vehicles/speedbike.dm b/code/modules/vehicles/speedbike.dm index 3db99e736b..21d8cff1be 100644 --- a/code/modules/vehicles/speedbike.dm +++ b/code/modules/vehicles/speedbike.dm @@ -4,7 +4,7 @@ icon_state = "speedbike_blue" layer = LYING_MOB_LAYER var/overlay_state = "cover_blue" - var/image/overlay = null + var/static/mutable_appearance/overlay /obj/vehicle/space/speedbike/buckle_mob(mob/living/M, force = 0, check_loc = 1) . = ..() @@ -12,8 +12,7 @@ /obj/vehicle/space/speedbike/New() . = ..() - overlay = image("icons/obj/bike.dmi", overlay_state) - overlay.layer = ABOVE_MOB_LAYER + overlay = overlay || mutable_appearance(icon, overlay_state, ABOVE_MOB_LAYER) add_overlay(overlay) /obj/effect/overlay/temp/speedbike_trail diff --git a/tgstation.dme b/tgstation.dme index df3e306d8c..4eba97eef4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -247,6 +247,7 @@ #include "code\datums\martial.dm" #include "code\datums\material_container.dm" #include "code\datums\mind.dm" +#include "code\datums\mutable_appearance.dm" #include "code\datums\mutations.dm" #include "code\datums\outfit.dm" #include "code\datums\progressbar.dm" From 84321916a5c7741691a0a27d32a31050bf7f8c5e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 09:52:35 -0500 Subject: [PATCH 02/15] Refactors ears into organs (#513) * Refactors ear damage into ear organs * Update human.dm * Update species.dm * Delete species.dm.rej * Update tgstation.dme * Delete tgstation.dme.rej * Delete human.dm.rej * Update tongue.dm * Delete surgery.dmi * upload fixed surgery.dmi --- code/__DEFINES/flags.dm | 4 + code/__DEFINES/mobs.dm | 4 +- code/__HELPERS/priority_announce.dm | 4 +- .../diseases/advance/symptoms/deafness.dm | 11 +- .../diseases/advance/symptoms/sensory.dm | 5 +- .../gamemodes/changeling/powers/shriek.dm | 11 +- code/game/gamemodes/miniantags/borer/borer.dm | 2 +- code/game/gamemodes/wizard/artefact.dm | 2 +- .../game/objects/items/weapons/clown_items.dm | 17 +- code/game/sound.dm | 2 +- code/modules/clothing/clothing.dm | 1 + code/modules/mob/living/brain/status_procs.dm | 10 +- code/modules/mob/living/carbon/alien/alien.dm | 3 + code/modules/mob/living/carbon/carbon.dm | 3 + .../mob/living/carbon/carbon_defense.dm | 24 +- code/modules/mob/living/carbon/human/human.dm | 1 + code/modules/mob/living/carbon/human/life.dm | 12 +- .../mob/living/carbon/human/species.dm | 9 + .../mob/living/carbon/monkey/monkey.dm | 10 +- code/modules/mob/living/life.dm | 8 - code/modules/mob/living/living.dm | 2 - code/modules/mob/living/silicon/ai/say.dm | 2 +- .../mob/living/silicon/status_procs.dm | 8 - .../mob/living/simple_animal/status_procs.dm | 9 - code/modules/mob/living/status_procs.dm | 18 +- code/modules/mob/mob.dm | 8 +- code/modules/mob/mob_defines.dm | 2 - code/modules/mob/mob_helpers.dm | 3 + code/modules/mob/status_procs.dm | 8 - .../chemistry/reagents/medicine_reagents.dm | 2 +- code/modules/surgery/organs/appendix.dm | 32 + code/modules/surgery/organs/ears.dm | 69 ++ code/modules/surgery/organs/eyes.dm | 130 +++ code/modules/surgery/organs/heart.dm | 126 +++ code/modules/surgery/organs/lungs.dm | 267 ++++++ code/modules/surgery/organs/organ_internal.dm | 796 +----------------- code/modules/surgery/organs/tongue.dm | 200 +++++ code/modules/surgery/organs/vocal_cords.dm | 2 +- icons/obj/surgery.dmi | Bin 28021 -> 29118 bytes tgstation.dme | 6 + 40 files changed, 925 insertions(+), 908 deletions(-) create mode 100644 code/modules/surgery/organs/appendix.dm create mode 100644 code/modules/surgery/organs/ears.dm create mode 100644 code/modules/surgery/organs/eyes.dm create mode 100644 code/modules/surgery/organs/heart.dm create mode 100644 code/modules/surgery/organs/lungs.dm create mode 100644 code/modules/surgery/organs/tongue.dm diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index dc2e575f5d..6745645115 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -36,6 +36,10 @@ #define INFORM_ADMINS_ON_RELOCATE "inform_admins_on_relocate" #define BANG_PROTECT "bang_protect" +// An item worn in the ear slot with HEALS_EARS will heal your ears each +// Life() tick, even if normally your ears would be too damaged to heal. +#define HEALS_EARS "heals_ears" + // A mob with OMNITONGUE has no restriction in the ability to speak // languages that they know. So even if they wouldn't normally be able to // through mob or tongue restrictions, this flag allows them to ignore diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 21740c1b2b..a3570d840d 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -119,4 +119,6 @@ #define GALOSHES_DONT_HELP 4 #define SLIDE_ICE 8 -#define MAX_CHICKENS 50 \ No newline at end of file +#define MAX_CHICKENS 50 + +#define UNHEALING_EAR_DAMAGE 100 diff --git a/code/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm index 46d71dc0e2..c62a59ed77 100644 --- a/code/__HELPERS/priority_announce.dm +++ b/code/__HELPERS/priority_announce.dm @@ -25,7 +25,7 @@ announcement += "
" for(var/mob/M in GLOB.player_list) - if(!isnewplayer(M) && !M.ear_deaf) + if(!isnewplayer(M) && M.can_hear()) to_chat(M, announcement) if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS) M << sound(sound) @@ -51,7 +51,7 @@ return for(var/mob/M in GLOB.player_list) - if(!isnewplayer(M) && !M.ear_deaf) + if(!isnewplayer(M) && M.can_hear()) to_chat(M, "[title]
[message]

") if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS) if(alert) diff --git a/code/datums/diseases/advance/symptoms/deafness.dm b/code/datums/diseases/advance/symptoms/deafness.dm index f970ebe04c..cd9cb8350b 100644 --- a/code/datums/diseases/advance/symptoms/deafness.dm +++ b/code/datums/diseases/advance/symptoms/deafness.dm @@ -33,12 +33,5 @@ Bonus if(3, 4) to_chat(M, "[pick("You hear a ringing in your ear.", "Your ears pop.")]") if(5) - if(!(M.ear_deaf)) - to_chat(M, "Your ears pop and begin ringing loudly!") - M.setEarDamage(-1,INFINITY) //Shall be enough - addtimer(CALLBACK(src, .proc/Undeafen, M), 200) - -/datum/symptom/deafness/proc/Undeafen(mob/living/M) - if(M) - to_chat(M, "The ringing in your ears fades...") - M.setEarDamage(-1,0) \ No newline at end of file + to_chat(M, "Your ears pop and begin ringing loudly!") + M.minimumDeafTicks(20) diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index 536184c766..321d6691b3 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -28,7 +28,7 @@ Bonus ..() var/mob/living/M = A.affected_mob if(A.stage >= 2) - M.setEarDamage(0,0) + M.restoreEars() if(A.stage >= 3) M.dizziness = 0 @@ -50,7 +50,6 @@ Bonus if(A.stage >= 5) M.adjustBrainLoss(-3) - return /* ////////////////////////////////////// @@ -127,5 +126,3 @@ Bonus M.drowsyness += 1 if(24 to INFINITY) M.Sleeping(2, 0) - - return diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm index 29be040929..0b106b0b12 100644 --- a/code/game/gamemodes/changeling/powers/shriek.dm +++ b/code/game/gamemodes/changeling/powers/shriek.dm @@ -10,12 +10,13 @@ /obj/effect/proc_holder/changeling/resonant_shriek/sting_action(mob/user) for(var/mob/living/M in get_hearers_in_view(4, user)) if(iscarbon(M)) - if(!M.mind || !M.mind.changeling) - M.adjustEarDamage(0,30) - M.confused += 25 - M.Jitter(50) + var/mob/living/carbon/C = M + if(!C.mind || !C.mind.changeling) + C.adjustEarDamage(0, 30) + C.confused += 25 + C.Jitter(50) else - M << sound('sound/effects/screech.ogg') + C << sound('sound/effects/screech.ogg') if(issilicon(M)) M << sound('sound/weapons/flash.ogg') diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index 122d2c34ba..b10fb16768 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -770,7 +770,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10) if("Blindness") victim.blind_eyes(2) if("Deafness") - victim.ear_deaf = 20 + victim.minimumDeafTicks(20) if("Stun") victim.Weaken(10) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 13084fab64..c925a5cbd5 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -471,7 +471,7 @@ else if(istype(I,/obj/item/weapon/bikehorn)) to_chat(target, "HONK") target << 'sound/items/AirHorn.ogg' - target.adjustEarDamage(0,3) + target.adjustEarDamage(0,3) GiveHint(target) cooldown = world.time +cooldown_time return diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm index 1c2bf7511c..8c8b476113 100644 --- a/code/game/objects/items/weapons/clown_items.dm +++ b/code/game/objects/items/weapons/clown_items.dm @@ -105,7 +105,7 @@ throw_speed = 3 throw_range = 7 attack_verb = list("HONKED") - var/spam_flag = 0 + var/next_usable = 0 var/honksound = 'sound/items/bikehorn.ogg' var/cooldowntime = 20 @@ -115,18 +115,15 @@ return (BRUTELOSS) /obj/item/weapon/bikehorn/attack(mob/living/carbon/M, mob/living/carbon/user) - if(!spam_flag) + if(!(next_usable > world.time)) playsound(loc, honksound, 50, 1, -1) //plays instead of tap.ogg! return ..() /obj/item/weapon/bikehorn/attack_self(mob/user) - if(!spam_flag) - spam_flag = 1 + if(!(next_usable > world.time)) + next_usable = world.time + cooldowntime playsound(src.loc, honksound, 50, 1) src.add_fingerprint(user) - spawn(cooldowntime) - spam_flag = 0 - return /obj/item/weapon/bikehorn/Crossed(mob/living/L) if(isliving(L)) @@ -156,12 +153,12 @@ ..() /obj/item/weapon/bikehorn/golden/proc/flip_mobs(mob/living/carbon/M, mob/user) - if (!spam_flag) + if(!(next_usable > world.time)) var/turf/T = get_turf(src) for(M in ohearers(7, T)) - if(ishuman(M)) + if(ishuman(M) && M.can_hear()) var/mob/living/carbon/human/H = M - if((istype(H.ears, /obj/item/clothing/ears/earmuffs)) || H.ear_deaf) + if(istype(H.ears, /obj/item/clothing/ears/earmuffs)) continue M.emote("flip") diff --git a/code/game/sound.dm b/code/game/sound.dm index 0c9e8d189a..448f3cd85b 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -81,7 +81,7 @@ src << S /mob/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, surround = 1, channel = 0, pressure_affected = TRUE) - if(!client || ear_deaf > 0) + if(!client || !can_hear()) return ..() diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 3b5b93ce6f..26b052d2ce 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -201,6 +201,7 @@ /obj/item/clothing/ears/earmuffs/Initialize(mapload) ..() SET_SECONDARY_FLAG(src, BANG_PROTECT) + SET_SECONDARY_FLAG(src, HEALS_EARS) //Glasses /obj/item/clothing/glasses diff --git a/code/modules/mob/living/brain/status_procs.dm b/code/modules/mob/living/brain/status_procs.dm index caf2bfe22c..4c40973c20 100644 --- a/code/modules/mob/living/brain/status_procs.dm +++ b/code/modules/mob/living/brain/status_procs.dm @@ -1,15 +1,7 @@ //Here are the procs used to modify status effects of a mob. -//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage, +//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness // eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability. -/////////////////////////////////// EAR DAMAGE //////////////////////////////////// - -/mob/living/brain/adjustEarDamage() - return - -/mob/living/brain/setEarDamage() // no ears to damage or heal - return - /////////////////////////////////// EYE_BLIND //////////////////////////////////// /mob/living/brain/blind_eyes() // no eyes to damage or heal diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 78c3e4e1df..5e1a91113f 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -48,6 +48,7 @@ internal_organs += new /obj/item/organ/alien/hivenode internal_organs += new /obj/item/organ/tongue/alien internal_organs += new /obj/item/organ/eyes/night_vision/alien + internal_organs += new /obj/item/organ/ears ..() /mob/living/carbon/alien/assess_threat() // beepsky won't hunt aliums @@ -147,6 +148,8 @@ Des: Removes all infected images from the alien. mind.transfer_to(new_xeno) qdel(src) + // TODO make orbiters orbit the new xeno, or make xenos species rather than types + #undef HEAT_DAMAGE_LEVEL_1 #undef HEAT_DAMAGE_LEVEL_2 #undef HEAT_DAMAGE_LEVEL_3 diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 97686940bd..36035b9ae1 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -722,6 +722,9 @@ if(reagents) reagents.addiction_list = list() ..() + // heal ears after healing disabilities, since ears check DEAF disability + // when healing. + restoreEars() /mob/living/carbon/can_be_revived() . = ..() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index bce7889758..0d8cfeb98d 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -277,20 +277,24 @@ /mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 1, damage_pwr = 5, deafen_pwr = 15) var/ear_safety = get_ear_protection() + var/obj/item/organ/ears/ears = getorganslot("ears") if(ear_safety < 2) //has ears var/effect_amount = intensity - ear_safety if(effect_amount > 0) if(stun_pwr) Stun(stun_pwr*effect_amount) Weaken(stun_pwr*effect_amount) - if(deafen_pwr || damage_pwr) - setEarDamage(ear_damage + damage_pwr*effect_amount, max(ear_deaf, deafen_pwr*effect_amount)) - if (ear_damage >= 15) + if(istype(ears) && (deafen_pwr || damage_pwr)) + ears.ear_damage += damage_pwr * effect_amount + ears.deaf = max(ears.deaf, deafen_pwr * effect_amount) + + if(ears.ear_damage >= 15) to_chat(src, "Your ears start to ring badly!") - if(prob(ear_damage - 5)) - to_chat(src, "You can't hear anything!") - disabilities |= DEAF - else if(ear_damage >= 5) + if(prob(ears.ear_damage - 5)) + to_chat(src, "You can't hear anything!") + ears.ear_damage = min(ears.ear_damage, UNHEALING_EAR_DAMAGE) + // you need earmuffs, inacusiate, or replacement + else if(ears.ear_damage >= 5) to_chat(src, "Your ears start to ring!") src << sound('sound/weapons/flash_ring.ogg',0,1,0,250) return effect_amount //how soundbanged we are @@ -310,3 +314,9 @@ hit_clothes = head if(hit_clothes) hit_clothes.take_damage(damage_amount, damage_type, damage_flag, 0) + +/mob/living/carbon/can_hear() + . = FALSE + var/obj/item/organ/ears/ears = getorganslot("ears") + if(istype(ears) && !ears.deaf) + . = TRUE diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 8b9899d067..ebbe18ff11 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -59,6 +59,7 @@ internal_organs += new /obj/item/organ/heart internal_organs += new dna.species.mutanteyes() + internal_organs += new dna.species.mutantears internal_organs += new /obj/item/organ/brain give_genitals() ..() diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index af815756c1..7324e156a4 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -70,18 +70,8 @@ else if(eye_blurry) //blurry eyes heal slowly adjust_blurriness(-1) - //Ears - if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own - setEarDamage(-1, max(ear_deaf, 1)) - else - if(istype(ears, /obj/item/clothing/ears/earmuffs)) // earmuffs rest your ears, healing ear_deaf faster and ear_damage, but keeping you deaf. - setEarDamage(max(ear_damage-0.10, 0), max(ear_deaf - 1, 1)) - // deafness heals slowly over time, unless ear_damage is over 100 - if(ear_damage < 100) - adjustEarDamage(-0.05,-1) - if (getBrainLoss() >= 60 && stat != DEAD) - if (prob(3)) + if(prob(3)) if(prob(25)) emote("drool") else diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 71b607c928..2f5cddb4d7 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -67,6 +67,9 @@ //Eyes var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes + + //Ears + var/obj/item/organ/ears/mutantears = /obj/item/organ/ears //Citadel snowflake var/fixed_mut_color2 = "" @@ -127,6 +130,7 @@ var/obj/item/organ/lungs/lungs = C.getorganslot("lungs") var/obj/item/organ/appendix/appendix = C.getorganslot("appendix") var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight") + var/obj/item/organ/ears/ears = C.getorganslot("ears") if((NOBLOOD in species_traits) && heart) heart.Remove(C) @@ -144,6 +148,11 @@ eyes = new mutanteyes eyes.Insert(C) + if(ears) + qdel(ears) + ears = new mutantears + ears.Insert(C) + if((!(NOBREATH in species_traits)) && !lungs) if(mutantlungs) lungs = new mutantlungs() diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index e5af3d5904..34017d6728 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -45,6 +45,7 @@ internal_organs += new /obj/item/organ/brain internal_organs += new /obj/item/organ/tongue internal_organs += new /obj/item/organ/eyes + internal_organs += new /obj/item/organ/ears ..() /mob/living/carbon/monkey/movement_delay() @@ -134,15 +135,6 @@ protection = protection/7 //the rest of the body isn't covered. return protection -/mob/living/carbon/monkey/fully_heal(admin_revive = 0) - if(!getorganslot("lungs")) - var/obj/item/organ/lungs/L = new() - L.Insert(src) - if(!getorganslot("tongue")) - var/obj/item/organ/tongue/T = new() - T.Insert(src) - ..() - /mob/living/carbon/monkey/IsVocal() if(!getorganslot("lungs")) return 0 diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 1ab7177b72..8a15572aa0 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -126,14 +126,6 @@ if(client && !eye_blurry) clear_fullscreen("blurry") - //Ears - if(disabilities & DEAF) //disabled-deaf, doesn't get better on its own - setEarDamage(-1, max(ear_deaf, 1)) - else - // deafness heals slowly over time, unless ear_damage is over 100 - if(ear_damage < 100) - adjustEarDamage(-0.05,-1) - /mob/living/proc/update_damage_hud() return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 8187dde9aa..e3502e7a90 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -379,8 +379,6 @@ cure_blind() cure_husk() disabilities = 0 - ear_deaf = 0 - ear_damage = 0 hallucination = 0 heal_overall_damage(100000, 100000, 0, 0, 1) //heal brute and burn dmg on both organic and robotic limbs, and update health right away. ExtinguishMob() diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 3aeec1035d..4080cea4fb 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -153,7 +153,7 @@ if(!only_listener) // Play voice for all mobs in the z level for(var/mob/M in GLOB.player_list) - if(M.client && !M.ear_deaf && (M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)) + if(M.client && M.can_hear() && (M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)) var/turf/T = get_turf(M) if(T.z == z_level) M << voice diff --git a/code/modules/mob/living/silicon/status_procs.dm b/code/modules/mob/living/silicon/status_procs.dm index c14e6c254f..3947cb020f 100644 --- a/code/modules/mob/living/silicon/status_procs.dm +++ b/code/modules/mob/living/silicon/status_procs.dm @@ -36,11 +36,3 @@ . = ..() if(. && updating) update_stat() - -/////////////////////////////////// EAR DAMAGE //////////////////////////////////// - -/mob/living/silicon/adjustEarDamage() - return - -/mob/living/silicon/setEarDamage() - return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/status_procs.dm b/code/modules/mob/living/simple_animal/status_procs.dm index fd90f825a3..62a262f9e6 100644 --- a/code/modules/mob/living/simple_animal/status_procs.dm +++ b/code/modules/mob/living/simple_animal/status_procs.dm @@ -23,12 +23,3 @@ /mob/living/simple_animal/become_blind() return - - - -/mob/living/simple_animal/adjustEarDamage() - return - -/mob/living/simple_animal/setEarDamage() - return - diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index f26fd04e59..9fe8443506 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -1,21 +1,7 @@ //Here are the procs used to modify status effects of a mob. -//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage, +//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, // eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability. -/////////////////////////////////// EAR DAMAGE //////////////////////////////////// - -//damage/heal the mob ears and adjust the deaf amount -/mob/living/adjustEarDamage(damage, deaf) - ear_damage = max(0, ear_damage + damage) - ear_deaf = max(0, ear_deaf + deaf) - -//pass a negative argument to skip one of the variable -/mob/living/setEarDamage(damage, deaf) - if(damage >= 0) - ear_damage = damage - if(deaf >= 0) - ear_deaf = deaf - //////////////////////////////STUN //////////////////////////////////// @@ -71,4 +57,4 @@ to_chat(src, "[priority_absorb_key["self_message"]]") priority_absorb_key["stuns_absorbed"] += amount return 0 - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 07aaa98fbc..95e034fd96 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -73,7 +73,7 @@ msg = alt_msg type = alt_type - if(type & 2 && ear_deaf)//Hearing related + if(type & 2 && !can_hear())//Hearing related if(!alt_msg) return else @@ -972,10 +972,6 @@ set_eye_damage(var_value) if("eye_blurry") set_blurriness(var_value) - if("ear_deaf") - setEarDamage(-1, var_value) - if("ear_damage") - setEarDamage(var_value, -1) if("maxHealth") updatehealth() if("resize") @@ -1013,4 +1009,4 @@ switch(var_name) if("logging") return debug_variable(var_name, logging, 0, src, FALSE) - . = ..() \ No newline at end of file + . = ..() diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 998613bb37..82dca7986b 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -42,8 +42,6 @@ var/notransform = null //Carbon var/eye_blind = 0 //Carbon var/eye_blurry = 0 //Carbon - var/ear_deaf = 0 //Carbon - var/ear_damage = 0 //Carbon var/stuttering = 0 //Carbon var/slurring = 0 //Carbon var/cultslurring = 0 //Carbon diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 729e924261..1e748776bf 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -482,3 +482,6 @@ It's fairly easy to fix if dealing with single letters but not so much with comp var/list/timestamped_message = list("[LAZYLEN(logging[message_type]) + 1]\[[time_stamp()]\] [key_name(src)]" = message) logging[message_type] += timestamped_message + +/mob/proc/can_hear() + . = TRUE diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index caa5a38326..f12e7d6d4e 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -143,14 +143,6 @@ /mob/proc/Dizzy(amount) dizziness = max(dizziness,amount,0) -/////////////////////////////////// EAR DAMAGE //////////////////////////////////// - -/mob/proc/adjustEarDamage() - return - -/mob/proc/setEarDamage() - return - /////////////////////////////////// EYE DAMAGE //////////////////////////////////// /mob/proc/damage_eyes(amount) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 29ca2df931..dee5b7e68a 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -118,7 +118,7 @@ color = "#6600FF" // rgb: 100, 165, 255 /datum/reagent/medicine/inacusiate/on_mob_life(mob/living/M) - M.setEarDamage(0,0) + M.restoreEars() ..() /datum/reagent/medicine/cryoxadone diff --git a/code/modules/surgery/organs/appendix.dm b/code/modules/surgery/organs/appendix.dm new file mode 100644 index 0000000000..ad51c48d85 --- /dev/null +++ b/code/modules/surgery/organs/appendix.dm @@ -0,0 +1,32 @@ +/obj/item/organ/appendix + name = "appendix" + icon_state = "appendix" + zone = "groin" + slot = "appendix" + var/inflamed = 0 + +/obj/item/organ/appendix/update_icon() + if(inflamed) + icon_state = "appendixinflamed" + name = "inflamed appendix" + else + icon_state = "appendix" + name = "appendix" + +/obj/item/organ/appendix/Remove(mob/living/carbon/M, special = 0) + for(var/datum/disease/appendicitis/A in M.viruses) + A.cure() + inflamed = 1 + update_icon() + ..() + +/obj/item/organ/appendix/Insert(mob/living/carbon/M, special = 0) + ..() + if(inflamed) + M.AddDisease(new /datum/disease/appendicitis) + +/obj/item/organ/appendix/prepare_eat() + var/obj/S = ..() + if(inflamed) + S.reagents.add_reagent("bad_food", 5) + return S diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm new file mode 100644 index 0000000000..c35cf5c670 --- /dev/null +++ b/code/modules/surgery/organs/ears.dm @@ -0,0 +1,69 @@ +/obj/item/organ/ears + name = "ears" + icon_state = "ears" + desc = "There are three parts to the ear. Inner, middle and outer. Only one of these parts should be normally visible." + zone = "head" + slot = "ears" + + // `deaf` measures "ticks" of deafness. While > 0, the person is unable + // to hear anything. + var/deaf = 0 + + // `ear_damage` measures long term damage to the ears, if too high, + // the person will not have either `deaf` or `ear_damage` decrease + // without external aid (earmuffs, drugs) + var/ear_damage = 0 + +/obj/item/organ/ears/on_life() + if(!iscarbon(owner)) + return + var/mob/living/carbon/C = owner + // genetic deafness prevents the body from using the ears, even if healthy + if(C.disabilities & DEAF) + deaf = max(deaf, 1) + else + if(HAS_SECONDARY_FLAG(C.ears, HEALS_EARS)) + deaf = max(deaf - 1, 1) + ear_damage = max(ear_damage - 0.10, 0) + // if higher than UNHEALING_EAR_DAMAGE, no natural healing occurs. + if(ear_damage < UNHEALING_EAR_DAMAGE) + ear_damage = max(ear_damage - 0.05, 0) + deaf = max(deaf - 1, 0) + +/obj/item/organ/ears/proc/restoreEars() + deaf = 0 + ear_damage = 0 + + var/mob/living/carbon/C = owner + + if(iscarbon(owner) && C.disabilities & DEAF) + deaf = 1 + +/obj/item/organ/ears/proc/adjustEarDamage(ddmg, ddeaf) + ear_damage = max(ear_damage + ddmg, 0) + deaf = max(deaf + ddeaf, 0) + +/obj/item/organ/ears/proc/minimumDeafTicks(value) + deaf = max(deaf, value) + + +/mob/proc/restoreEars() + +/mob/living/carbon/restoreEars() + var/obj/item/organ/ears/ears = getorgan(/obj/item/organ/ears) + if(ears) + ears.restoreEars() + +/mob/proc/adjustEarDamage() + +/mob/living/carbon/adjustEarDamage(ddmg, ddeaf) + var/obj/item/organ/ears/ears = getorgan(/obj/item/organ/ears) + if(ears) + ears.adjustEarDamage(ddmg, ddeaf) + +/mob/proc/minimumDeafTicks() + +/mob/living/carbon/minimumDeafTicks(value) + var/obj/item/organ/ears/ears = getorgan(/obj/item/organ/ears) + if(ears) + ears.minimumDeafTicks(value) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm new file mode 100644 index 0000000000..672ac924ad --- /dev/null +++ b/code/modules/surgery/organs/eyes.dm @@ -0,0 +1,130 @@ +/obj/item/organ/eyes + name = "eyes" + icon_state = "eyeballs" + desc = "I see you!" + zone = "eyes" + slot = "eye_sight" + + var/sight_flags = 0 + var/see_in_dark = 2 + var/tint = 0 + var/eye_color = "" //set to a hex code to override a mob's eye color + var/old_eye_color = "fff" + var/flash_protect = 0 + var/see_invisible = SEE_INVISIBLE_LIVING + var/lighting_alpha + +/obj/item/organ/eyes/Insert(mob/living/carbon/M, special = 0) + ..() + if(ishuman(owner)) + var/mob/living/carbon/human/HMN = owner + old_eye_color = HMN.eye_color + if(eye_color) + HMN.eye_color = eye_color + HMN.regenerate_icons() + else + eye_color = HMN.eye_color + M.update_tint() + owner.update_sight() + +/obj/item/organ/eyes/Remove(mob/living/carbon/M, special = 0) + ..() + if(ishuman(M) && eye_color) + var/mob/living/carbon/human/HMN = M + HMN.eye_color = old_eye_color + HMN.regenerate_icons() + M.update_tint() + M.update_sight() + +/obj/item/organ/eyes/night_vision + name = "shadow eyes" + desc = "A spooky set of eyes that can see in the dark." + see_in_dark = 8 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + actions_types = list(/datum/action/item_action/organ_action/use) + var/night_vision = TRUE + +/obj/item/organ/eyes/night_vision/ui_action_click() + switch(lighting_alpha) + if (LIGHTING_PLANE_ALPHA_VISIBLE) + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) + lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE + else + lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + owner.update_sight() + +/obj/item/organ/eyes/night_vision/alien + name = "alien eyes" + desc = "It turned out they had them after all!" + see_in_dark = 8 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + sight_flags = SEE_MOBS + + +///Robotic + +/obj/item/organ/eyes/robotic + name = "robotic eyes" + icon_state = "cybernetic_eyeballs" + desc = "Your vision is augmented." + status = ORGAN_ROBOTIC + +/obj/item/organ/eyes/robotic/emp_act(severity) + if(!owner) + return + if(severity > 1) + if(prob(10 * severity)) + return + to_chat(owner, "Static obfuscates your vision!") + owner.flash_act(visual = 1) + +/obj/item/organ/eyes/robotic/xray + name = "X-ray eyes" + desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." + eye_color = "000" + see_in_dark = 8 + sight_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS + +/obj/item/organ/eyes/robotic/thermals + name = "Thermals eyes" + desc = "These cybernetic eye implants will give you Thermal vision. Vertical slit pupil included." + eye_color = "FC0" + origin_tech = "materials=5;programming=4;biotech=4;magnets=4;syndicate=1" + sight_flags = SEE_MOBS + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + flash_protect = -1 + see_in_dark = 8 + +/obj/item/organ/eyes/robotic/flashlight + name = "flashlight eyes" + desc = "It's two flashlights rigged together with some wire. Why would you put these in someones head?" + eye_color ="fee5a3" + icon = 'icons/obj/lighting.dmi' + icon_state = "flashlight_eyes" + flash_protect = 2 + tint = INFINITY + +/obj/item/organ/eyes/robotic/flashlight/emp_act(severity) + return + +/obj/item/organ/eyes/robotic/flashlight/Insert(var/mob/living/carbon/M, var/special = 0) + ..() + M.set_light(M.light_range + 15, M.light_power + 1) + + +/obj/item/organ/eyes/robotic/flashlight/Remove(var/mob/living/carbon/M, var/special = 0) + M.set_light(M.light_range -15, M.light_power - 1) + ..() + +// Welding shield implant +/obj/item/organ/eyes/robotic/shield + name = "shielded robotic eyes" + desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." + origin_tech = "materials=4;biotech=3;engineering=4;plasmatech=3" + flash_protect = 2 + +/obj/item/organ/eyes/robotic/shield/emp_act(severity) + return diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm new file mode 100644 index 0000000000..9ffe8b6d06 --- /dev/null +++ b/code/modules/surgery/organs/heart.dm @@ -0,0 +1,126 @@ +/obj/item/organ/heart + name = "heart" + icon_state = "heart-on" + zone = "chest" + slot = "heart" + origin_tech = "biotech=5" + // Heart attack code is in code/modules/mob/living/carbon/human/life.dm + var/beating = 1 + var/icon_base = "heart" + attack_verb = list("beat", "thumped") + +/obj/item/organ/heart/update_icon() + if(beating) + icon_state = "[icon_base]-on" + else + icon_state = "[icon_base]-off" + +/obj/item/organ/heart/Remove(mob/living/carbon/M, special = 0) + ..() + if(!special) + addtimer(CALLBACK(src, .proc/stop_if_unowned), 120) + +/obj/item/organ/heart/proc/stop_if_unowned() + if(!owner) + Stop() + +/obj/item/organ/heart/attack_self(mob/user) + ..() + if(!beating) + visible_message("[user] squeezes [src] to \ + make it beat again!", "You squeeze \ + [src] to make it beat again!") + Restart() + addtimer(CALLBACK(src, .proc/stop_if_unowned), 80) + +/obj/item/organ/heart/proc/Stop() + beating = 0 + update_icon() + return 1 + +/obj/item/organ/heart/proc/Restart() + beating = 1 + update_icon() + return 1 + +/obj/item/organ/heart/prepare_eat() + var/obj/S = ..() + S.icon_state = "heart-off" + return S + + +/obj/item/organ/heart/cursed + name = "cursed heart" + desc = "A heart that, when inserted, will force you to pump it manually." + icon_state = "cursedheart-off" + icon_base = "cursedheart" + origin_tech = "biotech=6" + actions_types = list(/datum/action/item_action/organ_action/cursed_heart) + var/last_pump = 0 + var/add_colour = TRUE //So we're not constantly recreating colour datums + var/pump_delay = 30 //you can pump 1 second early, for lag, but no more (otherwise you could spam heal) + var/blood_loss = 100 //600 blood is human default, so 5 failures (below 122 blood is where humans die because reasons?) + + //How much to heal per pump, negative numbers would HURT the player + var/heal_brute = 0 + var/heal_burn = 0 + var/heal_oxy = 0 + + +/obj/item/organ/heart/cursed/attack(mob/living/carbon/human/H, mob/living/carbon/human/user, obj/target) + if(H == user && istype(H)) + playsound(user,'sound/effects/singlebeat.ogg',40,1) + user.drop_item() + Insert(user) + else + return ..() + +/obj/item/organ/heart/cursed/on_life() + if(world.time > (last_pump + pump_delay)) + if(ishuman(owner) && owner.client) //While this entire item exists to make people suffer, they can't control disconnects. + var/mob/living/carbon/human/H = owner + if(H.dna && !(NOBLOOD in H.dna.species.species_traits)) + H.blood_volume = max(H.blood_volume - blood_loss, 0) + to_chat(H, "You have to keep pumping your blood!") + if(add_colour) + H.add_client_colour(/datum/client_colour/cursed_heart_blood) //bloody screen so real + add_colour = FALSE + else + last_pump = world.time //lets be extra fair *sigh* + +/obj/item/organ/heart/cursed/Insert(mob/living/carbon/M, special = 0) + ..() + if(owner) + to_chat(owner, "Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!") + +/datum/action/item_action/organ_action/cursed_heart + name = "Pump your blood" + +//You are now brea- pumping blood manually +/datum/action/item_action/organ_action/cursed_heart/Trigger() + . = ..() + if(. && istype(target,/obj/item/organ/heart/cursed)) + var/obj/item/organ/heart/cursed/cursed_heart = target + + if(world.time < (cursed_heart.last_pump + (cursed_heart.pump_delay-10))) //no spam + to_chat(owner, "Too soon!") + return + + cursed_heart.last_pump = world.time + playsound(owner,'sound/effects/singlebeat.ogg',40,1) + to_chat(owner, "Your heart beats.") + + var/mob/living/carbon/human/H = owner + if(istype(H)) + if(H.dna && !(NOBLOOD in H.dna.species.species_traits)) + H.blood_volume = min(H.blood_volume + cursed_heart.blood_loss*0.5, BLOOD_VOLUME_MAXIMUM) + H.remove_client_colour(/datum/client_colour/cursed_heart_blood) + cursed_heart.add_colour = TRUE + H.adjustBruteLoss(-cursed_heart.heal_brute) + H.adjustFireLoss(-cursed_heart.heal_burn) + H.adjustOxyLoss(-cursed_heart.heal_oxy) + + +/datum/client_colour/cursed_heart_blood + priority = 100 //it's an indicator you're dieing, so it's very high priority + colour = "red" diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm new file mode 100644 index 0000000000..ece2ad3f40 --- /dev/null +++ b/code/modules/surgery/organs/lungs.dm @@ -0,0 +1,267 @@ +#define HUMAN_MAX_OXYLOSS 3 +#define HUMAN_CRIT_MAX_OXYLOSS (SSmobs.wait/30) +#define HEAT_GAS_DAMAGE_LEVEL_1 2 +#define HEAT_GAS_DAMAGE_LEVEL_2 4 +#define HEAT_GAS_DAMAGE_LEVEL_3 8 + +#define COLD_GAS_DAMAGE_LEVEL_1 0.5 +#define COLD_GAS_DAMAGE_LEVEL_2 1.5 +#define COLD_GAS_DAMAGE_LEVEL_3 3 + +/obj/item/organ/lungs + name = "lungs" + icon_state = "lungs" + zone = "chest" + slot = "lungs" + gender = PLURAL + w_class = WEIGHT_CLASS_NORMAL + var/list/breathlevels = list("safe_oxygen_min" = 16,"safe_oxygen_max" = 0,"safe_co2_min" = 0,"safe_co2_max" = 10, + "safe_toxins_min" = 0,"safe_toxins_max" = 0.05,"SA_para_min" = 1,"SA_sleep_min" = 5,"BZ_trip_balls_min" = 1) + + //Breath damage + + var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa + var/safe_oxygen_max = 0 + var/safe_co2_min = 0 + var/safe_co2_max = 10 // Yes it's an arbitrary value who cares? + var/safe_toxins_min = 0 + var/safe_toxins_max = 0.05 + var/SA_para_min = 1 //Sleeping agent + var/SA_sleep_min = 5 //Sleeping agent + var/BZ_trip_balls_min = 1 //BZ gas. + + var/oxy_breath_dam_min = 1 + var/oxy_breath_dam_max = 10 + var/co2_breath_dam_min = 1 + var/co2_breath_dam_max = 10 + var/tox_breath_dam_min = MIN_PLASMA_DAMAGE + var/tox_breath_dam_max = MAX_PLASMA_DAMAGE + + + +/obj/item/organ/lungs/proc/check_breath(datum/gas_mixture/breath, var/mob/living/carbon/human/H) + if((H.status_flags & GODMODE)) + return + + var/species_traits = list() + if(H && H.dna && H.dna.species && H.dna.species.species_traits) + species_traits = H.dna.species.species_traits + + if(!breath || (breath.total_moles() == 0)) + if(H.reagents.has_reagent("epinephrine")) + return + if(H.health >= HEALTH_THRESHOLD_CRIT) + H.adjustOxyLoss(HUMAN_MAX_OXYLOSS) + else if(!(NOCRITDAMAGE in species_traits)) + H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS) + + H.failed_last_breath = 1 + if(safe_oxygen_min) + H.throw_alert("oxy", /obj/screen/alert/oxy) + else if(safe_toxins_min) + H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox) + else if(safe_co2_min) + H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2) + return 0 + + var/gas_breathed = 0 + + var/list/breath_gases = breath.gases + + breath.assert_gases("o2", "plasma", "co2", "n2o", "bz") + + //Partial pressures in our breath + var/O2_pp = breath.get_breath_partial_pressure(breath_gases["o2"][MOLES]) + var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases["plasma"][MOLES]) + var/CO2_pp = breath.get_breath_partial_pressure(breath_gases["co2"][MOLES]) + + + //-- OXY --// + + //Too much oxygen! //Yes, some species may not like it. + if(safe_oxygen_max) + if(O2_pp > safe_oxygen_max) + var/ratio = (breath_gases["o2"][MOLES]/safe_oxygen_max) * 10 + H.adjustOxyLoss(Clamp(ratio,oxy_breath_dam_min,oxy_breath_dam_max)) + H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy) + else + H.clear_alert("too_much_oxy") + + //Too little oxygen! + if(safe_oxygen_min) + if(O2_pp < safe_oxygen_min) + gas_breathed = handle_too_little_breath(H,O2_pp,safe_oxygen_min,breath_gases["o2"][MOLES]) + H.throw_alert("oxy", /obj/screen/alert/oxy) + else + H.failed_last_breath = 0 + if(H.getOxyLoss()) + H.adjustOxyLoss(-5) + gas_breathed = breath_gases["o2"][MOLES] + H.clear_alert("oxy") + + //Exhale + breath_gases["o2"][MOLES] -= gas_breathed + breath_gases["co2"][MOLES] += gas_breathed + gas_breathed = 0 + + + //-- CO2 --// + + //CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick. + if(safe_co2_max) + if(CO2_pp > safe_co2_max) + if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so. + H.co2overloadtime = world.time + else if(world.time - H.co2overloadtime > 120) + H.Paralyse(3) + H.adjustOxyLoss(3) // Lets hurt em a little, let them know we mean business + if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good! + H.adjustOxyLoss(8) + H.throw_alert("too_much_co2", /obj/screen/alert/too_much_co2) + if(prob(20)) // Lets give them some chance to know somethings not right though I guess. + H.emote("cough") + + else + H.co2overloadtime = 0 + H.clear_alert("too_much_co2") + + //Too little CO2! + if(breathlevels["safe_co2_min"]) + if(CO2_pp < safe_co2_min) + gas_breathed = handle_too_little_breath(H,CO2_pp, safe_co2_min,breath_gases["co2"][MOLES]) + H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2) + else + H.failed_last_breath = 0 + H.adjustOxyLoss(-5) + gas_breathed = breath_gases["co2"][MOLES] + H.clear_alert("not_enough_co2") + + //Exhale + breath_gases["co2"][MOLES] -= gas_breathed + breath_gases["o2"][MOLES] += gas_breathed + gas_breathed = 0 + + + //-- TOX --// + + //Too much toxins! + if(safe_toxins_max) + if(Toxins_pp > safe_toxins_max) + var/ratio = (breath_gases["plasma"][MOLES]/safe_toxins_max) * 10 + if(H.reagents) + H.reagents.add_reagent("plasma", Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max)) + H.throw_alert("tox_in_air", /obj/screen/alert/tox_in_air) + else + H.clear_alert("tox_in_air") + + + //Too little toxins! + if(safe_toxins_min) + if(Toxins_pp < safe_toxins_min) + gas_breathed = handle_too_little_breath(H,Toxins_pp, safe_toxins_min, breath_gases["plasma"][MOLES]) + H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox) + else + H.failed_last_breath = 0 + H.adjustOxyLoss(-5) + gas_breathed = breath_gases["plasma"][MOLES] + H.clear_alert("not_enough_tox") + + //Exhale + breath_gases["plasma"][MOLES] -= gas_breathed + breath_gases["co2"][MOLES] += gas_breathed + gas_breathed = 0 + + + //-- TRACES --// + + if(breath) // If there's some other shit in the air lets deal with it here. + + // N2O + + var/SA_pp = breath.get_breath_partial_pressure(breath_gases["n2o"][MOLES]) + if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit + H.Paralyse(3) // 3 gives them one second to wake up and run away a bit! + if(SA_pp > SA_sleep_min) // Enough to make us sleep as well + H.Sleeping(max(H.sleeping+2, 10)) + else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning + if(prob(20)) + H.emote(pick("giggle", "laugh")) + + // BZ + + var/bz_pp = breath.get_breath_partial_pressure(breath_gases["bz"][MOLES]) + if(bz_pp > BZ_trip_balls_min) + H.hallucination += 20 + if(prob(33)) + H.adjustBrainLoss(3) + else if(bz_pp > 0.01) + H.hallucination += 5//Removed at 2 per tick so this will slowly build up + handle_breath_temperature(breath, H) + breath.garbage_collect() + + return 1 + + +/obj/item/organ/lungs/proc/handle_too_little_breath(mob/living/carbon/human/H = null,breath_pp = 0, safe_breath_min = 0, true_pp = 0) + . = 0 + if(!H || !safe_breath_min) //the other args are either: Ok being 0 or Specifically handled. + return 0 + + if(prob(20)) + H.emote("gasp") + if(breath_pp > 0) + var/ratio = safe_breath_min/breath_pp + H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS)) // Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all! + H.failed_last_breath = 1 + . = true_pp*ratio/6 + else + H.adjustOxyLoss(HUMAN_MAX_OXYLOSS) + H.failed_last_breath = 1 + + +/obj/item/organ/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures + if(abs(310.15 - breath.temperature) > 50) + + var/species_traits = list() + if(H && H.dna && H.dna.species && H.dna.species.species_traits) + species_traits = H.dna.species.species_traits + + if(!(GLOB.mutations_list[COLDRES] in H.dna.mutations) && !(RESISTCOLD in species_traits)) // COLD DAMAGE + switch(breath.temperature) + if(-INFINITY to 120) + H.apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, "head") + if(120 to 200) + H.apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, "head") + if(200 to 260) + H.apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head") + + if(!(RESISTHOT in species_traits)) // HEAT DAMAGE + switch(breath.temperature) + if(360 to 400) + H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head") + if(400 to 1000) + H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head") + if(1000 to INFINITY) + H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head") + +/obj/item/organ/lungs/prepare_eat() + var/obj/S = ..() + S.reagents.add_reagent("salbutamol", 5) + return S + +/obj/item/organ/lungs/plasmaman + name = "plasma filter" + + safe_oxygen_min = 0 //We don't breath this + safe_toxins_min = 16 //We breath THIS! + safe_toxins_max = 0 + +#undef HUMAN_MAX_OXYLOSS +#undef HUMAN_CRIT_MAX_OXYLOSS +#undef HEAT_GAS_DAMAGE_LEVEL_1 +#undef HEAT_GAS_DAMAGE_LEVEL_2 +#undef HEAT_GAS_DAMAGE_LEVEL_3 + +#undef COLD_GAS_DAMAGE_LEVEL_1 +#undef COLD_GAS_DAMAGE_LEVEL_2 +#undef COLD_GAS_DAMAGE_LEVEL_3 diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index c6c2a86728..f2503252b4 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -102,666 +102,34 @@ //Looking for brains? //Try code/modules/mob/living/carbon/brain/brain_item.dm - - -/obj/item/organ/heart - name = "heart" - icon_state = "heart-on" - zone = "chest" - slot = "heart" - origin_tech = "biotech=5" - // Heart attack code is in code/modules/mob/living/carbon/human/life.dm - var/beating = 1 - var/icon_base = "heart" - attack_verb = list("beat", "thumped") - -/obj/item/organ/heart/update_icon() - if(beating) - icon_state = "[icon_base]-on" - else - icon_state = "[icon_base]-off" - -/obj/item/organ/heart/Remove(mob/living/carbon/M, special = 0) - ..() - if(!special) - addtimer(CALLBACK(src, .proc/stop_if_unowned), 120) - -/obj/item/organ/heart/proc/stop_if_unowned() - if(!owner) - Stop() - -/obj/item/organ/heart/attack_self(mob/user) - ..() - if(!beating) - visible_message("[user] squeezes [src] to \ - make it beat again!", "You squeeze \ - [src] to make it beat again!") - Restart() - addtimer(CALLBACK(src, .proc/stop_if_unowned), 80) - -/obj/item/organ/heart/proc/Stop() - beating = 0 - update_icon() - return 1 - -/obj/item/organ/heart/proc/Restart() - beating = 1 - update_icon() - return 1 - -/obj/item/organ/heart/prepare_eat() - var/obj/S = ..() - S.icon_state = "heart-off" - return S - - -/obj/item/organ/heart/cursed - name = "cursed heart" - desc = "A heart that, when inserted, will force you to pump it manually." - icon_state = "cursedheart-off" - icon_base = "cursedheart" - origin_tech = "biotech=6" - actions_types = list(/datum/action/item_action/organ_action/cursed_heart) - var/last_pump = 0 - var/add_colour = TRUE //So we're not constantly recreating colour datums - var/pump_delay = 30 //you can pump 1 second early, for lag, but no more (otherwise you could spam heal) - var/blood_loss = 100 //600 blood is human default, so 5 failures (below 122 blood is where humans die because reasons?) - - //How much to heal per pump, negative numbers would HURT the player - var/heal_brute = 0 - var/heal_burn = 0 - var/heal_oxy = 0 - - -/obj/item/organ/heart/cursed/attack(mob/living/carbon/human/H, mob/living/carbon/human/user, obj/target) - if(H == user && istype(H)) - playsound(user,'sound/effects/singlebeat.ogg',40,1) - user.drop_item() - Insert(user) - else - return ..() - -/obj/item/organ/heart/cursed/on_life() - if(world.time > (last_pump + pump_delay)) - if(ishuman(owner) && owner.client) //While this entire item exists to make people suffer, they can't control disconnects. - var/mob/living/carbon/human/H = owner - if(H.dna && !(NOBLOOD in H.dna.species.species_traits)) - H.blood_volume = max(H.blood_volume - blood_loss, 0) - to_chat(H, "You have to keep pumping your blood!") - if(add_colour) - H.add_client_colour(/datum/client_colour/cursed_heart_blood) //bloody screen so real - add_colour = FALSE - else - last_pump = world.time //lets be extra fair *sigh* - -/obj/item/organ/heart/cursed/Insert(mob/living/carbon/M, special = 0) - ..() - if(owner) - to_chat(owner, "Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!") - -/datum/action/item_action/organ_action/cursed_heart - name = "Pump your blood" - -//You are now brea- pumping blood manually -/datum/action/item_action/organ_action/cursed_heart/Trigger() - . = ..() - if(. && istype(target,/obj/item/organ/heart/cursed)) - var/obj/item/organ/heart/cursed/cursed_heart = target - - if(world.time < (cursed_heart.last_pump + (cursed_heart.pump_delay-10))) //no spam - to_chat(owner, "Too soon!") - return - - cursed_heart.last_pump = world.time - playsound(owner,'sound/effects/singlebeat.ogg',40,1) - to_chat(owner, "Your heart beats.") - - var/mob/living/carbon/human/H = owner - if(istype(H)) - if(H.dna && !(NOBLOOD in H.dna.species.species_traits)) - H.blood_volume = min(H.blood_volume + cursed_heart.blood_loss*0.5, BLOOD_VOLUME_MAXIMUM) - H.remove_client_colour(/datum/client_colour/cursed_heart_blood) - cursed_heart.add_colour = TRUE - H.adjustBruteLoss(-cursed_heart.heal_brute) - H.adjustFireLoss(-cursed_heart.heal_burn) - H.adjustOxyLoss(-cursed_heart.heal_oxy) - - -/datum/client_colour/cursed_heart_blood - priority = 100 //it's an indicator you're dieing, so it's very high priority - colour = "red" - -#define HUMAN_MAX_OXYLOSS 3 -#define HUMAN_CRIT_MAX_OXYLOSS (SSmobs.wait/30) -#define HEAT_GAS_DAMAGE_LEVEL_1 2 -#define HEAT_GAS_DAMAGE_LEVEL_2 4 -#define HEAT_GAS_DAMAGE_LEVEL_3 8 - -#define COLD_GAS_DAMAGE_LEVEL_1 0.5 -#define COLD_GAS_DAMAGE_LEVEL_2 1.5 -#define COLD_GAS_DAMAGE_LEVEL_3 3 - -/obj/item/organ/lungs - name = "lungs" - icon_state = "lungs" - zone = "chest" - slot = "lungs" - gender = PLURAL - w_class = WEIGHT_CLASS_NORMAL - var/list/breathlevels = list("safe_oxygen_min" = 16,"safe_oxygen_max" = 0,"safe_co2_min" = 0,"safe_co2_max" = 10, - "safe_toxins_min" = 0,"safe_toxins_max" = 0.05,"SA_para_min" = 1,"SA_sleep_min" = 5,"BZ_trip_balls_min" = 1) - - //Breath damage - - var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa - var/safe_oxygen_max = 0 - var/safe_co2_min = 0 - var/safe_co2_max = 10 // Yes it's an arbitrary value who cares? - var/safe_toxins_min = 0 - var/safe_toxins_max = 0.05 - var/SA_para_min = 1 //Sleeping agent - var/SA_sleep_min = 5 //Sleeping agent - var/BZ_trip_balls_min = 1 //BZ gas. - - var/oxy_breath_dam_min = 1 - var/oxy_breath_dam_max = 10 - var/co2_breath_dam_min = 1 - var/co2_breath_dam_max = 10 - var/tox_breath_dam_min = MIN_PLASMA_DAMAGE - var/tox_breath_dam_max = MAX_PLASMA_DAMAGE - - - -/obj/item/organ/lungs/proc/check_breath(datum/gas_mixture/breath, var/mob/living/carbon/human/H) - if((H.status_flags & GODMODE)) - return - - var/species_traits = list() - if(H && H.dna && H.dna.species && H.dna.species.species_traits) - species_traits = H.dna.species.species_traits - - if(!breath || (breath.total_moles() == 0)) - if(H.reagents.has_reagent("epinephrine")) - return - if(H.health >= HEALTH_THRESHOLD_CRIT) - H.adjustOxyLoss(HUMAN_MAX_OXYLOSS) - else if(!(NOCRITDAMAGE in species_traits)) - H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS) - - H.failed_last_breath = 1 - if(safe_oxygen_min) - H.throw_alert("oxy", /obj/screen/alert/oxy) - else if(safe_toxins_min) - H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox) - else if(safe_co2_min) - H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2) - return 0 - - var/gas_breathed = 0 - - var/list/breath_gases = breath.gases - - breath.assert_gases("o2", "plasma", "co2", "n2o", "bz") - - //Partial pressures in our breath - var/O2_pp = breath.get_breath_partial_pressure(breath_gases["o2"][MOLES]) - var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases["plasma"][MOLES]) - var/CO2_pp = breath.get_breath_partial_pressure(breath_gases["co2"][MOLES]) - - - //-- OXY --// - - //Too much oxygen! //Yes, some species may not like it. - if(safe_oxygen_max) - if(O2_pp > safe_oxygen_max) - var/ratio = (breath_gases["o2"][MOLES]/safe_oxygen_max) * 10 - H.adjustOxyLoss(Clamp(ratio,oxy_breath_dam_min,oxy_breath_dam_max)) - H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy) - else - H.clear_alert("too_much_oxy") - - //Too little oxygen! - if(safe_oxygen_min) - if(O2_pp < safe_oxygen_min) - gas_breathed = handle_too_little_breath(H,O2_pp,safe_oxygen_min,breath_gases["o2"][MOLES]) - H.throw_alert("oxy", /obj/screen/alert/oxy) - else - H.failed_last_breath = 0 - if(H.getOxyLoss()) - H.adjustOxyLoss(-5) - gas_breathed = breath_gases["o2"][MOLES] - H.clear_alert("oxy") - - //Exhale - breath_gases["o2"][MOLES] -= gas_breathed - breath_gases["co2"][MOLES] += gas_breathed - gas_breathed = 0 - - - //-- CO2 --// - - //CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick. - if(safe_co2_max) - if(CO2_pp > safe_co2_max) - if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so. - H.co2overloadtime = world.time - else if(world.time - H.co2overloadtime > 120) - H.Paralyse(3) - H.adjustOxyLoss(3) // Lets hurt em a little, let them know we mean business - if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good! - H.adjustOxyLoss(8) - H.throw_alert("too_much_co2", /obj/screen/alert/too_much_co2) - if(prob(20)) // Lets give them some chance to know somethings not right though I guess. - H.emote("cough") - - else - H.co2overloadtime = 0 - H.clear_alert("too_much_co2") - - //Too little CO2! - if(breathlevels["safe_co2_min"]) - if(CO2_pp < safe_co2_min) - gas_breathed = handle_too_little_breath(H,CO2_pp, safe_co2_min,breath_gases["co2"][MOLES]) - H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2) - else - H.failed_last_breath = 0 - H.adjustOxyLoss(-5) - gas_breathed = breath_gases["co2"][MOLES] - H.clear_alert("not_enough_co2") - - //Exhale - breath_gases["co2"][MOLES] -= gas_breathed - breath_gases["o2"][MOLES] += gas_breathed - gas_breathed = 0 - - - //-- TOX --// - - //Too much toxins! - if(safe_toxins_max) - if(Toxins_pp > safe_toxins_max) - var/ratio = (breath_gases["plasma"][MOLES]/safe_toxins_max) * 10 - if(H.reagents) - H.reagents.add_reagent("plasma", Clamp(ratio, tox_breath_dam_min, tox_breath_dam_max)) - H.throw_alert("tox_in_air", /obj/screen/alert/tox_in_air) - else - H.clear_alert("tox_in_air") - - - //Too little toxins! - if(safe_toxins_min) - if(Toxins_pp < safe_toxins_min) - gas_breathed = handle_too_little_breath(H,Toxins_pp, safe_toxins_min, breath_gases["plasma"][MOLES]) - H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox) - else - H.failed_last_breath = 0 - H.adjustOxyLoss(-5) - gas_breathed = breath_gases["plasma"][MOLES] - H.clear_alert("not_enough_tox") - - //Exhale - breath_gases["plasma"][MOLES] -= gas_breathed - breath_gases["co2"][MOLES] += gas_breathed - gas_breathed = 0 - - - //-- TRACES --// - - if(breath) // If there's some other shit in the air lets deal with it here. - - // N2O - - var/SA_pp = breath.get_breath_partial_pressure(breath_gases["n2o"][MOLES]) - if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit - H.Paralyse(3) // 3 gives them one second to wake up and run away a bit! - if(SA_pp > SA_sleep_min) // Enough to make us sleep as well - H.Sleeping(max(H.sleeping+2, 10)) - else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning - if(prob(20)) - H.emote(pick("giggle", "laugh")) - - // BZ - - var/bz_pp = breath.get_breath_partial_pressure(breath_gases["bz"][MOLES]) - if(bz_pp > BZ_trip_balls_min) - H.hallucination += 20 - if(prob(33)) - H.adjustBrainLoss(3) - else if(bz_pp > 0.01) - H.hallucination += 5//Removed at 2 per tick so this will slowly build up - handle_breath_temperature(breath, H) - breath.garbage_collect() - - return 1 - - -/obj/item/organ/lungs/proc/handle_too_little_breath(mob/living/carbon/human/H = null,breath_pp = 0, safe_breath_min = 0, true_pp = 0) - . = 0 - if(!H || !safe_breath_min) //the other args are either: Ok being 0 or Specifically handled. - return 0 - - if(prob(20)) - H.emote("gasp") - if(breath_pp > 0) - var/ratio = safe_breath_min/breath_pp - H.adjustOxyLoss(min(5*ratio, HUMAN_MAX_OXYLOSS)) // Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all! - H.failed_last_breath = 1 - . = true_pp*ratio/6 - else - H.adjustOxyLoss(HUMAN_MAX_OXYLOSS) - H.failed_last_breath = 1 - - -/obj/item/organ/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures - if(abs(310.15 - breath.temperature) > 50) - - var/species_traits = list() - if(H && H.dna && H.dna.species && H.dna.species.species_traits) - species_traits = H.dna.species.species_traits - - if(!(GLOB.mutations_list[COLDRES] in H.dna.mutations) && !(RESISTCOLD in species_traits)) // COLD DAMAGE - switch(breath.temperature) - if(-INFINITY to 120) - H.apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, "head") - if(120 to 200) - H.apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, "head") - if(200 to 260) - H.apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head") - - if(!(RESISTHOT in species_traits)) // HEAT DAMAGE - switch(breath.temperature) - if(360 to 400) - H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head") - if(400 to 1000) - H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head") - if(1000 to INFINITY) - H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head") - - - - -/obj/item/organ/lungs/prepare_eat() - var/obj/S = ..() - S.reagents.add_reagent("salbutamol", 5) - return S - - -/obj/item/organ/lungs/plasmaman - name = "plasma filter" - - safe_oxygen_min = 0 //We don't breath this - safe_toxins_min = 16 //We breath THIS! - safe_toxins_max = 0 - - - - - -#undef HUMAN_MAX_OXYLOSS -#undef HUMAN_CRIT_MAX_OXYLOSS -#undef HEAT_GAS_DAMAGE_LEVEL_1 -#undef HEAT_GAS_DAMAGE_LEVEL_2 -#undef HEAT_GAS_DAMAGE_LEVEL_3 - -#undef COLD_GAS_DAMAGE_LEVEL_1 -#undef COLD_GAS_DAMAGE_LEVEL_2 -#undef COLD_GAS_DAMAGE_LEVEL_3 - -/obj/item/organ/tongue - name = "tongue" - desc = "A fleshy muscle mostly used for lying." - icon_state = "tonguenormal" - zone = "mouth" - slot = "tongue" - attack_verb = list("licked", "slobbered", "slapped", "frenched", "tongued") - var/list/languages_possible - var/say_mod = null - var/taste_sensitivity = 15 // lower is more sensitive. - -/obj/item/organ/tongue/Initialize(mapload) - ..() - languages_possible = typecacheof(list( - /datum/language/common, - /datum/language/monkey, - /datum/language/ratvar - )) - -/obj/item/organ/tongue/get_spans() - return list() - -/obj/item/organ/tongue/proc/TongueSpeech(var/message) - return message - -/obj/item/organ/tongue/Insert(mob/living/carbon/M, special = 0) - ..() - if(say_mod && M.dna && M.dna.species) - M.dna.species.say_mod = say_mod - -/obj/item/organ/tongue/Remove(mob/living/carbon/M, special = 0) - ..() - if(say_mod && M.dna && M.dna.species) - M.dna.species.say_mod = initial(M.dna.species.say_mod) - -/obj/item/organ/tongue/can_speak_in_language(datum/language/dt) - . = is_type_in_typecache(dt, languages_possible) - -/obj/item/organ/tongue/lizard - name = "forked tongue" - desc = "A thin and long muscle typically found in reptilian races, apparently moonlights as a nose." - icon_state = "tonguelizard" - say_mod = "hisses" - taste_sensitivity = 10 // combined nose + tongue, extra sensitive - -/obj/item/organ/tongue/lizard/TongueSpeech(var/message) - var/regex/lizard_hiss = new("s+", "g") - var/regex/lizard_hiSS = new("S+", "g") - if(copytext(message, 1, 2) != "*") - message = lizard_hiss.Replace(message, "sss") - message = lizard_hiSS.Replace(message, "SSS") - return message - -/obj/item/organ/tongue/fly - name = "proboscis" - desc = "A freakish looking meat tube that apparently can take in liquids." - icon_state = "tonguefly" - say_mod = "buzzes" - taste_sensitivity = 25 // you eat vomit, this is a mercy - -/obj/item/organ/tongue/fly/TongueSpeech(var/message) - var/regex/fly_buzz = new("z+", "g") - var/regex/fly_buZZ = new("Z+", "g") - if(copytext(message, 1, 2) != "*") - message = fly_buzz.Replace(message, "zzz") - message = fly_buZZ.Replace(message, "ZZZ") - return message - -/obj/item/organ/tongue/abductor - name = "superlingual matrix" - desc = "A mysterious structure that allows for instant communication between users. Pretty impressive until you need to eat something." - icon_state = "tongueayylmao" - say_mod = "gibbers" - taste_sensitivity = 101 // ayys cannot taste anything. - -/obj/item/organ/tongue/abductor/TongueSpeech(var/message) - //Hacks - var/mob/living/carbon/human/user = usr - var/rendered = "[user.name]: [message]" - for(var/mob/living/carbon/human/H in GLOB.living_mob_list) - var/obj/item/organ/tongue/T = H.getorganslot("tongue") - if(!T || T.type != type) - continue - else if(H.dna && H.dna.species.id == "abductor" && user.dna && user.dna.species.id == "abductor") - var/datum/species/abductor/Ayy = user.dna.species - var/datum/species/abductor/Byy = H.dna.species - if(Ayy.team != Byy.team) - continue - to_chat(H, rendered) - for(var/mob/M in GLOB.dead_mob_list) - var/link = FOLLOW_LINK(M, user) - to_chat(M, "[link] [rendered]") - return "" - -/obj/item/organ/tongue/zombie - name = "rotting tongue" - desc = "Between the decay and the fact that it's just lying there you doubt a tongue has ever seemed less sexy." - icon_state = "tonguezombie" - say_mod = "moans" - taste_sensitivity = 32 - -/obj/item/organ/tongue/zombie/TongueSpeech(var/message) - var/list/message_list = splittext(message, " ") - var/maxchanges = max(round(message_list.len / 1.5), 2) - - for(var/i = rand(maxchanges / 2, maxchanges), i > 0, i--) - var/insertpos = rand(1, message_list.len - 1) - var/inserttext = message_list[insertpos] - - if(!(copytext(inserttext, length(inserttext) - 2) == "...")) - message_list[insertpos] = inserttext + "..." - - if(prob(20) && message_list.len > 3) - message_list.Insert(insertpos, "[pick("BRAINS", "Brains", "Braaaiinnnsss", "BRAAAIIINNSSS")]...") - - return jointext(message_list, " ") - -/obj/item/organ/tongue/alien - name = "alien tongue" - desc = "According to leading xenobiologists the evolutionary benefit of having a second mouth in your mouth is \"that it looks badass\"." - icon_state = "tonguexeno" - say_mod = "hisses" - taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED - -/obj/item/organ/tongue/alien/Initialize(mapload) - ..() - languages_possible = typecacheof(list( - /datum/language/xenocommon, - /datum/language/common, - /datum/language/ratvar, - /datum/language/monkey)) - -/obj/item/organ/tongue/alien/TongueSpeech(var/message) - playsound(owner, "hiss", 25, 1, 1) - return message - -/obj/item/organ/tongue/bone - name = "bone \"tongue\"" - desc = "Apparently skeletons alter the sounds they produce \ - through oscillation of their teeth, hence their characteristic \ - rattling." - icon_state = "tonguebone" - say_mod = "rattles" - attack_verb = list("bitten", "chattered", "chomped", "enamelled", "boned") - taste_sensitivity = 101 // skeletons cannot taste anything - - var/chattering = FALSE - var/phomeme_type = "sans" - var/list/phomeme_types = list("sans", "papyrus") - -/obj/item/organ/tongue/bone/New() - . = ..() - phomeme_type = pick(phomeme_types) - -/obj/item/organ/tongue/bone/TongueSpeech(var/message) - . = message - - if(chattering) - //Annoy everyone nearby with your chattering. - chatter(message, phomeme_type, usr) - -/obj/item/organ/tongue/bone/get_spans() - . = ..() - // Feature, if the tongue talks directly, it will speak with its span - switch(phomeme_type) - if("sans") - . |= SPAN_SANS - if("papyrus") - . |= SPAN_PAPYRUS - -/obj/item/organ/tongue/bone/plasmaman - name = "plasma bone \"tongue\"" - desc = "Like animated skeletons, Plasmamen vibrate their teeth in order to produce speech." - icon_state = "tongueplasma" - -/obj/item/organ/tongue/bone/plasmaman/get_spans() - return - -/obj/item/organ/tongue/robot - name = "robotic voicebox" - desc = "A voice synthesizer that can interface with organic lifeforms." - status = ORGAN_ROBOTIC - icon_state = "tonguerobot" - say_mod = "states" - attack_verb = list("beeped", "booped") - taste_sensitivity = 25 // not as good as an organic tongue - -/obj/item/organ/tongue/robot/Initialize(mapload) - ..() - languages_possible = typecacheof(list( - /datum/language/xenocommon, - /datum/language/common, - /datum/language/ratvar, - /datum/language/monkey, - /datum/language/drone, - /datum/language/machine, - /datum/language/swarmer)) - -/obj/item/organ/tongue/robot/get_spans() - return ..() | SPAN_ROBOT - -/obj/item/organ/appendix - name = "appendix" - icon_state = "appendix" - zone = "groin" - slot = "appendix" - var/inflamed = 0 - -/obj/item/organ/appendix/update_icon() - if(inflamed) - icon_state = "appendixinflamed" - name = "inflamed appendix" - else - icon_state = "appendix" - name = "appendix" - -/obj/item/organ/appendix/Remove(mob/living/carbon/M, special = 0) - for(var/datum/disease/appendicitis/A in M.viruses) - A.cure() - inflamed = 1 - update_icon() - ..() - -/obj/item/organ/appendix/Insert(mob/living/carbon/M, special = 0) - ..() - if(inflamed) - M.AddDisease(new /datum/disease/appendicitis) - -/obj/item/organ/appendix/prepare_eat() - var/obj/S = ..() - if(inflamed) - S.reagents.add_reagent("bad_food", 5) - return S - /mob/living/proc/regenerate_organs() return 0 /mob/living/carbon/regenerate_organs() - CHECK_DNA_AND_SPECIES(src) + var/breathes = TRUE + var/blooded = TRUE + if(dna && dna.species) + if(NOBREATH in dna.species.species_traits) + breathes = FALSE + if(NOBLOOD in dna.species.species_traits) + blooded = FALSE - if(!(NOBREATH in dna.species.species_traits) && !getorganslot("lungs")) + if(breathes && !getorganslot("lungs")) var/obj/item/organ/lungs/L = new() L.Insert(src) - if(!(NOBLOOD in dna.species.species_traits) && !getorganslot("heart")) + if(blooded && !getorganslot("heart")) var/obj/item/organ/heart/H = new() H.Insert(src) if(!getorganslot("tongue")) var/obj/item/organ/tongue/T - for(var/tongue_type in dna.species.mutant_organs) - if(ispath(tongue_type, /obj/item/organ/tongue)) - T = new tongue_type() - T.Insert(src) + if(dna && dna.species) + for(var/tongue_type in dna.species.mutant_organs) + if(ispath(tongue_type, /obj/item/organ/tongue)) + T = new tongue_type() + T.Insert(src) // if they have no mutant tongues, give them a regular one if(!T) @@ -778,135 +146,11 @@ E = new() E.Insert(src) -//Eyes - -/obj/item/organ/eyes - name = "eyes" - icon_state = "eyeballs" - desc = "I see you!" - zone = "eyes" - slot = "eye_sight" - - var/sight_flags = 0 - var/see_in_dark = 2 - var/tint = 0 - var/eye_color = "" //set to a hex code to override a mob's eye color - var/old_eye_color = "fff" - var/flash_protect = 0 - var/see_invisible = SEE_INVISIBLE_LIVING - var/lighting_alpha - -/obj/item/organ/eyes/Insert(mob/living/carbon/M, special = 0) - ..() - if(ishuman(owner)) - var/mob/living/carbon/human/HMN = owner - old_eye_color = HMN.eye_color - if(eye_color) - HMN.eye_color = eye_color - HMN.regenerate_icons() + if(!getorganslot("ears")) + var/obj/item/organ/ears/ears + if(dna && dna.species && dna.species.mutantears) + ears = new dna.species.mutantears else - eye_color = HMN.eye_color - M.update_tint() - owner.update_sight() + ears = new -/obj/item/organ/eyes/Remove(mob/living/carbon/M, special = 0) - ..() - if(ishuman(M) && eye_color) - var/mob/living/carbon/human/HMN = M - HMN.eye_color = old_eye_color - HMN.regenerate_icons() - M.update_tint() - M.update_sight() - -/obj/item/organ/eyes/night_vision - name = "shadow eyes" - desc = "A spooky set of eyes that can see in the dark." - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - actions_types = list(/datum/action/item_action/organ_action/use) - var/night_vision = TRUE - -/obj/item/organ/eyes/night_vision/ui_action_click() - switch(lighting_alpha) - if (LIGHTING_PLANE_ALPHA_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE - else - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - owner.update_sight() - -/obj/item/organ/eyes/night_vision/alien - name = "alien eyes" - desc = "It turned out they had them after all!" - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - sight_flags = SEE_MOBS - - -///Robotic - -/obj/item/organ/eyes/robotic - name = "robotic eyes" - icon_state = "cybernetic_eyeballs" - desc = "Your vision is augmented." - status = ORGAN_ROBOTIC - -/obj/item/organ/eyes/robotic/emp_act(severity) - if(!owner) - return - if(severity > 1) - if(prob(10 * severity)) - return - to_chat(owner, "Static obfuscates your vision!") - owner.flash_act(visual = 1) - -/obj/item/organ/eyes/robotic/xray - name = "X-ray eyes" - desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." - eye_color = "000" - see_in_dark = 8 - sight_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS - -/obj/item/organ/eyes/robotic/thermals - name = "Thermals eyes" - desc = "These cybernetic eye implants will give you Thermal vision. Vertical slit pupil included." - eye_color = "FC0" - origin_tech = "materials=5;programming=4;biotech=4;magnets=4;syndicate=1" - sight_flags = SEE_MOBS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - flash_protect = -1 - see_in_dark = 8 - -/obj/item/organ/eyes/robotic/flashlight - name = "flashlight eyes" - desc = "It's two flashlights rigged together with some wire. Why would you put these in someones head?" - eye_color ="fee5a3" - icon = 'icons/obj/lighting.dmi' - icon_state = "flashlight_eyes" - flash_protect = 2 - tint = INFINITY - -/obj/item/organ/eyes/robotic/flashlight/emp_act(severity) - return - -/obj/item/organ/eyes/robotic/flashlight/Insert(var/mob/living/carbon/M, var/special = 0) - ..() - M.set_light(M.light_range + 15, M.light_power + 1) - - -/obj/item/organ/eyes/robotic/flashlight/Remove(var/mob/living/carbon/M, var/special = 0) - M.set_light(M.light_range -15, M.light_power - 1) - ..() - -// Welding shield implant -/obj/item/organ/eyes/robotic/shield - name = "shielded robotic eyes" - desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." - origin_tech = "materials=4;biotech=3;engineering=4;plasmatech=3" - flash_protect = 2 - -/obj/item/organ/eyes/robotic/shield/emp_act(severity) - return + ears.Insert(src) \ No newline at end of file diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm new file mode 100644 index 0000000000..1ef36f3fe2 --- /dev/null +++ b/code/modules/surgery/organs/tongue.dm @@ -0,0 +1,200 @@ +/obj/item/organ/tongue + name = "tongue" + desc = "A fleshy muscle mostly used for lying." + icon_state = "tonguenormal" + zone = "mouth" + slot = "tongue" + attack_verb = list("licked", "slobbered", "slapped", "frenched", "tongued") + var/list/languages_possible + var/say_mod = null + var/taste_sensitivity = 15 // lower is more sensitive. + +/obj/item/organ/tongue/Initialize(mapload) + ..() + languages_possible = typecacheof(list( + /datum/language/common, + /datum/language/monkey, + /datum/language/ratvar + )) + +/obj/item/organ/tongue/get_spans() + return list() + +/obj/item/organ/tongue/proc/TongueSpeech(var/message) + return message + +/obj/item/organ/tongue/Insert(mob/living/carbon/M, special = 0) + ..() + if(say_mod && M.dna && M.dna.species) + M.dna.species.say_mod = say_mod + +/obj/item/organ/tongue/Remove(mob/living/carbon/M, special = 0) + ..() + if(say_mod && M.dna && M.dna.species) + M.dna.species.say_mod = initial(M.dna.species.say_mod) + +/obj/item/organ/tongue/can_speak_in_language(datum/language/dt) + . = is_type_in_typecache(dt, languages_possible) + +/obj/item/organ/tongue/lizard + name = "forked tongue" + desc = "A thin and long muscle typically found in reptilian races, apparently moonlights as a nose." + icon_state = "tonguelizard" + say_mod = "hisses" + taste_sensitivity = 10 // combined nose + tongue, extra sensitive + +/obj/item/organ/tongue/lizard/TongueSpeech(var/message) + var/regex/lizard_hiss = new("s+", "g") + var/regex/lizard_hiSS = new("S+", "g") + if(copytext(message, 1, 2) != "*") + message = lizard_hiss.Replace(message, "sss") + message = lizard_hiSS.Replace(message, "SSS") + return message + +/obj/item/organ/tongue/fly + name = "proboscis" + desc = "A freakish looking meat tube that apparently can take in liquids." + icon_state = "tonguefly" + say_mod = "buzzes" + taste_sensitivity = 25 // you eat vomit, this is a mercy + +/obj/item/organ/tongue/fly/TongueSpeech(var/message) + var/regex/fly_buzz = new("z+", "g") + var/regex/fly_buZZ = new("Z+", "g") + if(copytext(message, 1, 2) != "*") + message = fly_buzz.Replace(message, "zzz") + message = fly_buZZ.Replace(message, "ZZZ") + return message + +/obj/item/organ/tongue/abductor + name = "superlingual matrix" + desc = "A mysterious structure that allows for instant communication between users. Pretty impressive until you need to eat something." + icon_state = "tongueayylmao" + say_mod = "gibbers" + taste_sensitivity = 101 // ayys cannot taste anything. + +/obj/item/organ/tongue/abductor/TongueSpeech(var/message) + //Hacks + var/mob/living/carbon/human/user = usr + var/rendered = "[user.name]: [message]" + for(var/mob/living/carbon/human/H in GLOB.living_mob_list) + var/obj/item/organ/tongue/T = H.getorganslot("tongue") + if(!T || T.type != type) + continue + else if(H.dna && H.dna.species.id == "abductor" && user.dna && user.dna.species.id == "abductor") + var/datum/species/abductor/Ayy = user.dna.species + var/datum/species/abductor/Byy = H.dna.species + if(Ayy.team != Byy.team) + continue + to_chat(H, rendered) + for(var/mob/M in GLOB.dead_mob_list) + var/link = FOLLOW_LINK(M, user) + to_chat(M, "[link] [rendered]") + return "" + +/obj/item/organ/tongue/zombie + name = "rotting tongue" + desc = "Between the decay and the fact that it's just lying there you doubt a tongue has ever seemed less sexy." + icon_state = "tonguezombie" + say_mod = "moans" + taste_sensitivity = 32 + +/obj/item/organ/tongue/zombie/TongueSpeech(var/message) + var/list/message_list = splittext(message, " ") + var/maxchanges = max(round(message_list.len / 1.5), 2) + + for(var/i = rand(maxchanges / 2, maxchanges), i > 0, i--) + var/insertpos = rand(1, message_list.len - 1) + var/inserttext = message_list[insertpos] + + if(!(copytext(inserttext, length(inserttext) - 2) == "...")) + message_list[insertpos] = inserttext + "..." + + if(prob(20) && message_list.len > 3) + message_list.Insert(insertpos, "[pick("BRAINS", "Brains", "Braaaiinnnsss", "BRAAAIIINNSSS")]...") + + return jointext(message_list, " ") + +/obj/item/organ/tongue/alien + name = "alien tongue" + desc = "According to leading xenobiologists the evolutionary benefit of having a second mouth in your mouth is \"that it looks badass\"." + icon_state = "tonguexeno" + say_mod = "hisses" + taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED + +/obj/item/organ/tongue/alien/Initialize(mapload) + ..() + languages_possible = typecacheof(list( + /datum/language/xenocommon, + /datum/language/common, + /datum/language/ratvar, + /datum/language/monkey)) + +/obj/item/organ/tongue/alien/TongueSpeech(var/message) + playsound(owner, "hiss", 25, 1, 1) + return message + +/obj/item/organ/tongue/bone + name = "bone \"tongue\"" + desc = "Apparently skeletons alter the sounds they produce \ + through oscillation of their teeth, hence their characteristic \ + rattling." + icon_state = "tonguebone" + say_mod = "rattles" + attack_verb = list("bitten", "chattered", "chomped", "enamelled", "boned") + taste_sensitivity = 101 // skeletons cannot taste anything + + var/chattering = FALSE + var/phomeme_type = "sans" + var/list/phomeme_types = list("sans", "papyrus") + +/obj/item/organ/tongue/bone/New() + . = ..() + phomeme_type = pick(phomeme_types) + +/obj/item/organ/tongue/bone/TongueSpeech(var/message) + . = message + + if(chattering) + //Annoy everyone nearby with your chattering. + chatter(message, phomeme_type, usr) + +/obj/item/organ/tongue/bone/get_spans() + . = ..() + // Feature, if the tongue talks directly, it will speak with its span + switch(phomeme_type) + if("sans") + . |= SPAN_SANS + if("papyrus") + . |= SPAN_PAPYRUS + +/obj/item/organ/tongue/bone/plasmaman + name = "plasma bone \"tongue\"" + desc = "Like animated skeletons, Plasmamen vibrate their teeth in order to produce speech." + icon_state = "tongueplasma" + +/obj/item/organ/tongue/bone/plasmaman/get_spans() + return + +/obj/item/organ/tongue/robot + name = "robotic voicebox" + desc = "A voice synthesizer that can interface with organic lifeforms." + status = ORGAN_ROBOTIC + icon_state = "tonguerobot" + say_mod = "states" + attack_verb = list("beeped", "booped") + taste_sensitivity = 25 // not as good as an organic tongue + +/obj/item/organ/tongue/robot/Initialize(mapload) + ..() + languages_possible = typecacheof(list( + /datum/language/xenocommon, + /datum/language/common, + /datum/language/ratvar, + /datum/language/monkey, + /datum/language/drone, + /datum/language/machine, + /datum/language/swarmer)) + +/obj/item/organ/tongue/robot/get_spans() + return ..() | SPAN_ROBOT diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index e844918eeb..2413a45870 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -107,7 +107,7 @@ message = lowertext(message) var/mob/living/list/listeners = list() for(var/mob/living/L in get_hearers_in_view(8, user)) - if(!L.ear_deaf && !L.null_rod_check() && L != user && L.stat != DEAD) + if(L.can_hear() && !L.null_rod_check() && L != user && L.stat != DEAD) if(ishuman(L)) var/mob/living/carbon/human/H = L if(istype(H.ears, /obj/item/clothing/ears/earmuffs)) diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index d1adc2919618d53772c33f0547247ddbac01e200..19d6275d785108cfeac96ebff99ccaeeddd9bbd8 100644 GIT binary patch delta 9915 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

-1uQ6HI3igIm>xliTF?6QeaTQVEyWIehabp47~F0=S?1q9IgFK@d_ne{Ohn~$+4_CM{X@V!a~ylor&Z) zD%*YG#;+JVWSq1~{YU*-h2YOk&5KpoQz4T?qAgdtN8*?qys}wJHSzC`vOO+6J^ibn zOO90)rNcA5i+r^Jbi=ju9L_l#xPK8D--Q|9N+LkQKMb+zO9ESlz4}K=-RzQ zOAL%{PxHQHp3s0=&PC!6=~e4%hgv7Q*=^1$#6M#KhT0OKd<^=JeE1V(-#atRv^DP& zy@XG5o^|!vi;Kp_*~Z_40Y-8zUf71~&fm3b_Z7;Tt)jtUe9DbjPgN*Xyp(yEPIGI5 zg=~TS{wD8CpX;7RT0fM0qj2hv#V7MLVory}H)1VI$AI2e_j)Yqp>04bC#>spYgpJo z2&Tm9w~ukaE)~Q^a{0^0WMv%^PK`kj4^Oe-uFBfHoUG2Ckqmo5&@V7_p~7UKzKPw@FC@1q5L3uRM(jnz^sa6b%379*lh+Uup` zzP`qL1}GV&lA9)Bd?$NYv&2h6xZ2uXM=`>wYXbx5x~v}O5`CzJ?}8#zglrq zSq|@8Xsx)`+U6MSXP>@AUHDom>$LXl{)mCDtqtj?%>)OE2MF_*i=~w`8|2JFC@4(Q0;z zTDLJ|+2{gM7*=CgbFTFoa!y{(dM@js%BF&iP3JB?Kkda2LW~88xuet*dUJoa)2c z)WjPkWh8R$ef{TuwyrP`x7yGUR(oo04DMuQx$)P-&K|a_>c&#^4@&*uhq+BDae#c2 z{hbMZyND16S(XTG9zFfMnyRuOyY^{SX?taCS65e|Rqsb}Rfqz~Ovm=^d-3fGmf@6v zn;%>c45i7Nm6JGhz*^MdrkDq7`Ytx=R3J7sOid} z6#f_TL?p<`*-B869>+j)dd1XWF9`GcnWI{+4{8);ZZ1Dt)=m0AmGS?T$XM~Lb{eKKZGK@7 z=bpBKGUz54NFjtjZ>_3wp5M~d)kXEaKW@1_1gmlI)=ZbudB#%2a;EN09DK}ckQ%eu z{5MR|JEmi~t;lfkfR0auGt4|=G-f-s)$GKtb=fHE_?x)Odw_lURA^( zFjj1_OM_Z>byi8LAI;dkwN%{Q&8TaNkqX2dp@7Pbe~*l9-5h|L!p^#BhBG)DF;UN%3KyNi$W%PI>k~4bqd1UBfg)bD=QVB*vsd>$enBPd>c5L+UmcfXWC`+f|dbJj2_{)e76!I>9Zrl!7;Km zCeih_W^`cKZJ96l{9eh6w7BE3t+>2As-y%oZ4eR(?|eae2Rnr~E30a}m=VN=+Q?yT zJn535r*bCXmW^*0@vZO%pUI2^2Rb#m!b_M42E9*vV|l}?odM$kJbZlRWp?Px1j6Gr zOl|HDw)>Z#Hl!|oEo?`=EfW^j&PkPb`bplf5NB&)@$fdZu3&Xl{twy+mMW0DQ7j(g;C=QtGMd=wWSf8??B>!QvV329h zoN!bu_wQ~m1{r%K#^kASP%3=CMKpTkNRoRNZ*!A0IyP2Gn=G8@7mVFP5IQllUv~YT zobg1$Sy_Bqj9>QMyHP;A*u=GpDZJ`zxeuvDQx|J4w$3_M^ zcc`e+@Yl{>?Edx&zbY8uLisP)FCqrY$CxQeNkmgugwR{JzjZiXAv}if`FvZg-}3Z$ z?(z`r80bfH;g-cJwoyj2lG|=pRMrS6gpeEy{i+7qNMfNtUowkQs}sWIi$=kiJT2o5 zwuVyE=jxlb*7)ZynlEe608KLl=Gec18lCG4DWIOBe1>bEZKPOp}P0wBQov} zdH9mIaP!565wfJcHG-td0VXfmprP*5Ioo2}3~3gHs&Wp6QpZ)f}dT7pKjX+KlRE0(Iz~)9uMh z;yJu~8MfF|>36#`I{liq^$M8*ZsAVquA{~27)Vk&hnJlP5Uwj-*6%!E5WC&vk^6sG z8u|x?5?6*>PVVd9h6l;volP{i$?*|0P*E`n45}x#bf$A7A$X z$xHt*fDZ0^95Bh<%A2{{05)Lszfb))HY-DS-ERtf9S7)>!1a}#*+Wm^%WQMQfnx&n`KW^lwV%qudrQJKe^Qf1XBazA!|`EH@geckVm0g^SRgkFCy)H+ar0>lN43 z5X?BuR??yDOw|&xrG`R3+P&(Sx@qu~#d-{eoAvWiIRcwYbMk>N145oBR4)DZCY?}cAO~1Gxire{E|QNy0pCofA5?$*bSZqJFzui zcr7hyIz9|MP$Ry31UAA{md+Vgtojl=A39R3fnm^#iILH#=FfVfD{thiNZ1pP?3ciz z4Ht|7gX0b7J%kLbEro`B4Jd{>n`2A*1_q+r=Wii=J(y{yoGUBlNQvU!)b{uI7=}C~ zQ)0o3iTL-uSbJJw9}m2R%_Vh4eAR_ER6WaaLQr!eI3vVCwk8l3$YXx6WGAmip2Ifq zy9n{qx5uZtJ6=AG-Pd(*xCEIM(9do2m-cnnO!!QO8Ph0{;>GTx)2z6ogMUEx=Wj0{ z$V2W&EY7}W{MXWhLI5xyQ%|5@l-IP&tFeWz$^h@asOP+e$^%mC)B=;t^`7MoJJqLL@ye=GXwD!$Qv0ong!Jg4E5 znsaA|*bF8Ynu~67GI$1;TACCJlaA-%>B@4So9#1xSRf+GhEN$3=OfP|($S^csi&aq zCNSJ5=9t`hu`z$dQ6=)r{|JlQ+go+MJWba(0&J-e40~Y{k?y|K+DA>m@Rv_X5Xqo| zWuuccp5m`sbO9b0h?dk+!PCE%2aA3mKZmWY$KF=t^cR=9-2*``)oY~Et3_b80p)MZ zcv@oB;dW7}an#UXKKTQF56^3+HSu|d-5Bp6e~%o>+o$BMQnK3fZ<9B?2;;E(7w9ZG zyGT^d6gp7)jfe?GTz!H2Q6Hq9_&U4L^Sw&nzcP_yYBD`q3x_|KK6ff5H`B2d9!a`J zX1m5Mj(l@)J{kvAUps=TaCTvxa!t0kIJQgr zwa+s%>^AQCt6!5A7g0oUn5=A-*5mbg<~R)EG40>8PP&>!yPKbSt|j0ZPsPps0x8Dd z3N5P8Y4iM#5+7A~`1l1W$py8M+WLPZ)B&5mi5*iWPp6ue&Sjl z&YrI}%-(2&@T8zkZnH6T=2G{T7Y$mvI6hp+o)vS`O(weG64r;W>LroXI8CI_T?q{k z)nOu^hS1(`-jM5S1|KZuY%UpwMoN=!u5Wdg$BUZ-T04q*F1Vp{FpE9; z=HWlTsm{cx4wzr{r62wJ%0kwyyp8YS-Z=MJ8{u8Nd{%;TIO3}yHeC?w-6wv+{~n8( z&K9D;79&eDnuI2)1IzzSiSRuX0cJHsr}rWcelHR!SK)>B8Ewo&0+GyQXhfBAESUMQ z@w!9Q#7`Tv#y_w?bXVzn>!!>_QdUjJO%6*Ib=O!kzRGnX%vZVbtxN$H^8M>+49;r~ zw45~2AmRi?<~Jd%{RNmQB+qbTi-D!D~R?!0!M^b!ZNv? z4y~M+X_%6WstW$4uzm+j%7H~}G&h@xKUsYcXIcdHU{*}y=id%-_`}@M+Jc7Vv?uWM zPs+zksbo})q>dEtON4aRVjFXPTwHw{M>1)fPzZf8aBt}UU^TLI%14+pBS4y0z1P&*r^yPz%ujN7*Sjq2+~`s2@>9etZ;iuL%Cr7%;`Z9+ zgjeME;@v3(1P~550E?n@SBzDO4nl0q0;E959y@+%z~A0XjE(6K?{ySy5JuaT z1xMnC*3U1l;62G6kS>K#tRYV>YA$PYT;}&-kL3+rC@450DhhAjYbI-y#N((5oLSmP z{Q3aS_?t)f*%m%-Ad|8vBhfK~lSyKj;Ee zltB}byZ{;<_GY=Am4ciR(g6Tb4dh~0`MkN5&B>tqZu>^#>N&UF}&?=AH-YqK9laG$~{AgBrnb=gawLAz#TP$nMM`y@~8cC z(Z{>*Y9{6qZ7b4RHZFQM0B_N&qq%U9KUE7R9e~YTrPzKQ8i!8XKk8Vzxwr2L?cb+_ zDJ)eK=XiQ5;##1#1|LjD&S|)|JY%?O6$*8hxX9W(`=U?sE>4_KEK?~d{J?{Mv55mC zz@aq%n&tEV*Cha%KQ%d)TFD9|NB22eZpO~4{W_oO44n4^=85jXBj((bX}*h!GW)8M z-Oh^?>0nWDQG>=;ovl}Nz35tfOL!Re(frbOK?P9n8m4$POGKv-Q{owx6r zy_va)U5G^hqH7j1UswY9@{RXaHt*%ZsLNBO%mlPe4{*%W29su2<6&^a#rQXA56n`Sdp@ zX}8mA={J}YRLrn(bLnzZ-(+l*e1BtU zDXYGgVC2vPuUQrRt8}W^vB(1@2~?w7ZdhxW^@~hkv_JC_V!6Wo#?>&S4f7fT5p56U=W@;DZO21=c_h9sx zUQIG7?g_KB1iQY~dpSS$tCczmjP5qF%$8Ic%_oW(_6Bvo-QC^hA5#~NwzYrTJli_b zeZRpI&lIxTZ;1&U|@;R0BB+K!#)~hz4$h+6ILF#lTf68(P4fnem`O- zWU}U$=rTqa4}q4Mf!LniV_=}vWpDl^3!Un_2~HR+X@{c)?s2UVdk4Iz(Z#3pM|65V zzf8y#M14+A$?y)2*0b#{Blt9QczWXX*f#lWL@hD59)cpvQfy3Vs z_{{!?5oPf#d~ky||MEU<=1R27acUr}6a^+i+(wn?jpD*B_d0p27inoVECh~;=q07S zina6x<~+38c#fGTME?-VMo}>lyeT+a=>eAg-rqC_@Ak6)x~g>RHJX#1J96dC6r^4n zABK+8$Y}Mjcld07fmnnK1DQnOvlqhM^~a_AYA0>=4#on=YQpEwsJw`gic!e0rtYIN zCW@w5^CHUd7qFSG+0MKbrq)(pF7~_UcJjY_#USY(_YI7p++peHOv2x@xU>E9^TUL&p-x9iNFJgS#PpZ^58*@S64f~Zm^0~y5J}nClxX`k z;!GWp3_ZHgmp$q7=8LoRL1N^7meH;y>#~uMN1%@ST;aZHrxJfCjHw;mFc-Go?-X6E z{h9l|XLe#tDc~m6wQ2G?J=UeAy#BCP6hTdZ&4I$;h2nbN&t-yf|7b?o<+vqb?MgEE z+{To_T}*1!(2vOhU}8vw@%4SC+DEPYW*MpH!OAQkkRJzEcytZPli3c;mvQ#~cYT0H zvgw&AU}ibK`fPhVSGAVt@l1Y7wi|5tB-LV?sr8rKYGnTdHEq7}&MpPYB*vY#);zGz z-|#YBtNoPed-{9-eXB?0GM4?4ruln5W3K%`kEzu!)GN6GxUg-OUqox+t}77m#VN=I zO5(?lwn|7EPH`J@Q%Eupo)8eaCPtaNX(|uZzpPQ%E(4{$d_GP^bb~%WHUDnOCp`)A zi#OYq)6T*oq^m1fgHAel%me8YA)%>DYku*bkg;p8i9ZC32K6J94Hm3uaM?VDw1@kK zDb|JAQPF_J@>B$&tC5tJ&6T}!Cc`EE4@am$Of`tA_yj^#|FY}l|GU$rV8|Mj^BwUs zJqKhSTz@a_%wDQJ@9{h?pt2L%>Fu{N*C27L<=tK{m)Ji%wBA3c#As?cC3J&a7OON$ z(7>U2goy!tk%Jq-*e_g7ABWdcd@9l@3;>C%dzqcBYT!DymPSZKd^yonr}F~-?MK?E@vewq5 znA3_@k_`&26bpvib&o$+XX-lzIgh{G^6#k$>=8-GRHjne>V8i55%&Vwus+xTdurB0 z_oMS?(=V^Q3V;73Q1ojoTkP#6^wvghAfp@N;_Kp8)22iaRM7wat}bJ2JLN|jUpC!| z9ug{}R<|xQbsY8B#b$v-+Y*UB|^Ft<_-4t!ZalRCoRX zvRtHuFwhbEanFS7W-74z!x89M((7Sfmq)3-IeZ-8iB-+0X&t6Y2J`baJ?vu2tG8 z;E@@D899DPTOgpo*ZBL2dvdbecJHazZAmM0=I@+5Ua(ha5El?70*Co-kCd`Vz-4ij z{3+P6ytqH2bdoRwHX|;B<)g%}oXZq5sMaUq)cXB}q>YYIda@mu4*Tfka0$M)X~$*u zXojiLzaG{QZ}e=jENR+ z7LVV?0#=1^!e%ooJnWcI9%Wp7bvzW2(8m(xn_PCNm2%O&Z+!_&WWad`|@%0l9 zq|j1oz5^IhvILG$2_wnCgAUPmut_yJ&CL;Tq5lWhDpVu@ diff --git a/tgstation.dme b/tgstation.dme index 4eba97eef4..1647912f6c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2093,14 +2093,20 @@ #include "code\modules\surgery\bodyparts\head.dm" #include "code\modules\surgery\bodyparts\helpers.dm" #include "code\modules\surgery\bodyparts\robot_bodyparts.dm" +#include "code\modules\surgery\organs\appendix.dm" #include "code\modules\surgery\organs\augments_arms.dm" #include "code\modules\surgery\organs\augments_chest.dm" #include "code\modules\surgery\organs\augments_eyes.dm" #include "code\modules\surgery\organs\augments_internal.dm" #include "code\modules\surgery\organs\autoimplanter.dm" #include "code\modules\surgery\organs\autosurgeon.dm" +#include "code\modules\surgery\organs\ears.dm" +#include "code\modules\surgery\organs\eyes.dm" +#include "code\modules\surgery\organs\heart.dm" #include "code\modules\surgery\organs\helpers.dm" +#include "code\modules\surgery\organs\lungs.dm" #include "code\modules\surgery\organs\organ_internal.dm" +#include "code\modules\surgery\organs\tongue.dm" #include "code\modules\surgery\organs\vocal_cords.dm" #include "code\modules\telesci\telepad.dm" #include "code\modules\telesci\telesci_computer.dm" From e0e1fe2422b234d9a6b64a7b5af2053238960860 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 09:52:36 -0500 Subject: [PATCH 03/15] Automatic changelog generation for PR #513 [ci skip] --- html/changelogs/AutoChangeLog-pr-513.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-513.yml diff --git a/html/changelogs/AutoChangeLog-pr-513.yml b/html/changelogs/AutoChangeLog-pr-513.yml new file mode 100644 index 0000000000..97ce1414d9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-513.yml @@ -0,0 +1,7 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "Centcom would like to inform all employees that they have ears." + - rscadd: "Adds \"ear\" organs to all carbons. These organs store ear damage and +deafness. A carbon without any ears is deaf. Genetic +deafness functions as before." From f8816839020de6483353119fd5790c192a27eac4 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 10:11:11 -0500 Subject: [PATCH 04/15] Fixes windows going invisible (#567) --- code/game/objects/structures/window.dm.rej | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 code/game/objects/structures/window.dm.rej diff --git a/code/game/objects/structures/window.dm.rej b/code/game/objects/structures/window.dm.rej new file mode 100644 index 0000000000..39a6d57678 --- /dev/null +++ b/code/game/objects/structures/window.dm.rej @@ -0,0 +1,23 @@ +diff a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm (rejected hunks) +@@ -18,7 +18,7 @@ + var/fulltile = 0 + var/glass_type = /obj/item/stack/sheet/glass + var/glass_amount = 1 +- var/static/mutable_appearance/crack_overlay = mutable_appearance('icons/obj/structures.dmi') ++ var/mutable_appearance/crack_overlay + var/list/debris = list() + can_be_unanchored = 1 + resistance_flags = ACID_PROOF +@@ -377,10 +377,10 @@ + if(smooth) + queue_smooth(src) + +- cut_overlays() ++ cut_overlay(crack_overlay) + if(ratio > 75) + return +- crack_overlay.icon_state = "damage[ratio]" ++ crack_overlay = mutable_appearance('icons/obj/structures.dmi', "damage[ratio]", -(layer+0.1)) + add_overlay(crack_overlay) + + /obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) From 4cf23d086af087e7fc0832521a7e89acd5b76131 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 10:11:22 -0500 Subject: [PATCH 05/15] Fixed nulls in the active_alternate_appearances list (#568) --- code/datums/hud.dm.rej | 10 ++++++++++ code/game/alternate_appearance.dm.rej | 19 +++++++++++++++++++ code/modules/mob/mob.dm.rej | 10 ++++++++++ 3 files changed, 39 insertions(+) create mode 100644 code/datums/hud.dm.rej create mode 100644 code/game/alternate_appearance.dm.rej create mode 100644 code/modules/mob/mob.dm.rej diff --git a/code/datums/hud.dm.rej b/code/datums/hud.dm.rej new file mode 100644 index 0000000000..3696e8b8fe --- /dev/null +++ b/code/datums/hud.dm.rej @@ -0,0 +1,10 @@ +diff a/code/datums/hud.dm b/code/datums/hud.dm (rejected hunks) +@@ -80,7 +80,7 @@ GLOBAL_LIST_INIT(huds, list( + gang_huds += G.ganghud + + for(var/datum/atom_hud/hud in (GLOB.huds|gang_huds|GLOB.active_alternate_appearances)) +- if(hud.hudusers[src]) ++ if(hud && hud.hudusers[src]) + hud.add_hud_to(src) + + /mob/dead/new_player/reload_huds() diff --git a/code/game/alternate_appearance.dm.rej b/code/game/alternate_appearance.dm.rej new file mode 100644 index 0000000000..52f96ceabd --- /dev/null +++ b/code/game/alternate_appearance.dm.rej @@ -0,0 +1,19 @@ +diff a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm (rejected hunks) +@@ -29,12 +29,11 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances) + appearance_key = key + + /datum/atom_hud/alternate_appearance/Destroy() +- if(!QDELETED(src)) +- for(var/v in hudusers) +- remove_hud_from(v) +- for(var/v in hudatoms) +- remove_from_hud(v) +- GLOB.active_alternate_appearances -= src ++ for(var/v in hudusers) ++ remove_hud_from(v) ++ for(var/v in hudatoms) ++ remove_from_hud(v) ++ GLOB.active_alternate_appearances -= src + return ..() + + /datum/atom_hud/alternate_appearance/proc/onNewMob(mob/M) diff --git a/code/modules/mob/mob.dm.rej b/code/modules/mob/mob.dm.rej new file mode 100644 index 0000000000..cff44187b0 --- /dev/null +++ b/code/modules/mob/mob.dm.rej @@ -0,0 +1,10 @@ +diff a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm (rejected hunks) +@@ -29,6 +29,8 @@ + prepare_huds() + can_ride_typecache = typecacheof(can_ride_typecache) + for(var/v in GLOB.active_alternate_appearances) ++ if(!v) ++ continue + var/datum/atom_hud/alternate_appearance/AA = v + AA.onNewMob(src) + ..() From b1d6b6a277232159d7525fd2338bbf6cda4bfadb Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 10:11:33 -0500 Subject: [PATCH 06/15] [MIRROR] Drake swooping is smoother and more dangerous (#571) * Drake swooping is smoother and more dangerous * Update dragon.dm * Delete dragon.dm.rej --- code/game/objects/effects/overlays.dm | 3 +- .../hostile/megafauna/bubblegum.dm | 5 +- .../simple_animal/hostile/megafauna/dragon.dm | 287 ++++++++++++------ icons/mob/lavaland/dragon.dmi | Bin 41255 -> 42396 bytes 4 files changed, 203 insertions(+), 92 deletions(-) diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 3d62e850e8..bc9251d9fc 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -35,7 +35,6 @@ ..() if(randomdir) setDir(pick(GLOB.cardinal)) - flick("[icon_state]", src) //Because we might be pulling it from a pool, flick whatever icon it uses so it starts at the start of the icon's animation. timerid = QDEL_IN(src, duration) @@ -214,7 +213,7 @@ icon = 'icons/effects/fire.dmi' icon_state = "3" duration = 20 - + /obj/effect/overlay/temp/cult randomdir = 0 duration = 10 diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 2e64ee526e..fa61a16e51 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -150,7 +150,7 @@ Difficulty: Hard var/turf/T = get_turf(target) if(!T || T == loc) return - new /obj/effect/overlay/temp/dragon_swoop(T) + new /obj/effect/overlay/temp/dragon_swoop/bubblegum(T) charging = TRUE DestroySurroundings() walk(src, 0) @@ -276,6 +276,9 @@ Difficulty: Hard addtimer(CALLBACK(src, .proc/devour, L), 2) sleep(1) +/obj/effect/overlay/temp/dragon_swoop/bubblegum + duration = 10 + /obj/effect/overlay/temp/bubblegum_hands icon = 'icons/effects/bubblegum.dmi' duration = 9 diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm index c56e963aef..3425d08e23 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm @@ -1,4 +1,10 @@ #define MEDAL_PREFIX "Drake" + +#define DRAKE_SWOOP_HEIGHT 270 //how high up drakes go, in pixels +#define DRAKE_SWOOP_DIRECTION_CHANGE_RANGE 5 //the range our x has to be within to not change the direction we slam from + +#define SWOOP_DAMAGEABLE 1 +#define SWOOP_INVULNERABLE 2 /* ASH DRAKE @@ -9,8 +15,9 @@ It acts as a melee creature, chasing down and attacking its target while also us Whenever possible, the drake will breathe fire in the four cardinal directions, igniting and heavily damaging anything caught in the blast. It also often causes fire to rain from the sky - many nearby turfs will flash red as a fireball crashes into them, dealing damage to anything on the turfs. -The drake also utilizes its wings to fly into the sky and crash down onto a specified point. Anything on this point takes tremendous damage. +The drake also utilizes its wings to fly into the sky, flying after its target and attempting to slam down on them. Anything near when it slams down takes huge damage. - Sometimes it will chain these swooping attacks over and over, making swiftness a necessity. + - Sometimes, it will spew fire while flying at its target. When an ash drake dies, it leaves behind a chest that can contain four things: 1. A spectral blade that allows its wielder to call ghosts to it, enhancing its power @@ -46,7 +53,7 @@ Difficulty: Medium pixel_x = -16 loot = list(/obj/structure/closet/crate/necropolis/dragon) butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30) - var/swooping = 0 + var/swooping = NONE var/swoop_cooldown = 0 medal_type = MEDAL_PREFIX score_type = DRAKE_SCORE @@ -63,10 +70,15 @@ Difficulty: Medium ..() /mob/living/simple_animal/hostile/megafauna/dragon/adjustHealth(amount, updating_health = TRUE, forced = FALSE) - if(!forced && swooping) + if(!forced && (swooping & SWOOP_INVULNERABLE)) return FALSE return ..() +/mob/living/simple_animal/hostile/megafauna/dragon/visible_message() + if(swooping & SWOOP_INVULNERABLE) //to suppress attack messages without overriding every single proc that could send a message saying we got hit + return + return ..() + /mob/living/simple_animal/hostile/megafauna/dragon/AttackingTarget() if(!swooping) return ..() @@ -86,62 +98,15 @@ Difficulty: Medium /mob/living/simple_animal/hostile/megafauna/dragon/Process_Spacemove(movement_dir = 0) return 1 -/obj/effect/overlay/temp/fireball - icon = 'icons/obj/wizard.dmi' - icon_state = "fireball" - name = "fireball" - desc = "Get out of the way!" - layer = FLY_LAYER - randomdir = 0 - duration = 12 - pixel_z = 500 - -/obj/effect/overlay/temp/fireball/Initialize(loc) - . = ..() - animate(src, pixel_z = 0, time = 12) - -/obj/effect/overlay/temp/target - icon = 'icons/mob/actions.dmi' - icon_state = "sniper_zoom" - layer = BELOW_MOB_LAYER - light_range = 2 - duration = 12 - -/obj/effect/overlay/temp/dragon_swoop - name = "certain death" - desc = "Don't just stand there, move!" - icon = 'icons/effects/96x96.dmi' - icon_state = "landing" - layer = BELOW_MOB_LAYER - pixel_x = -32 - pixel_y = -32 - color = "#FF0000" - duration = 10 - -/obj/effect/overlay/temp/target/ex_act() - return - -/obj/effect/overlay/temp/target/Initialize(loc) - . = ..() - INVOKE_ASYNC(src, .proc/fall) - -/obj/effect/overlay/temp/target/proc/fall() - var/turf/T = get_turf(src) - playsound(T,'sound/magic/Fireball.ogg', 200, 1) - new /obj/effect/overlay/temp/fireball(T) - sleep(12) - explosion(T, 0, 0, 1, 0, 0, 0, 1) - /mob/living/simple_animal/hostile/megafauna/dragon/OpenFire() + if(swooping) + return anger_modifier = Clamp(((maxHealth - health)/50),0,20) ranged_cooldown = world.time + ranged_cooldown_time - if(swooping) - fire_rain() - return if(prob(15 + anger_modifier) && !client) if(health < maxHealth/2) - INVOKE_ASYNC(src, .proc/swoop_attack, 1) + INVOKE_ASYNC(src, .proc/swoop_attack, TRUE, null, 50) else fire_rain() @@ -154,9 +119,11 @@ Difficulty: Medium fire_walls() /mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_rain() - visible_message("Fire rains from the sky!") - for(var/turf/turf in range(12,get_turf(src))) - if(prob(10)) + if(!target) + return + target.visible_message("Fire rains from the sky!") + for(var/turf/turf in range(9,get_turf(target))) + if(prob(11)) new /obj/effect/overlay/temp/target(turf) /mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_walls() @@ -177,6 +144,8 @@ Difficulty: Medium new /obj/effect/hotspot(J) J.hotspot_expose(700,50,1) for(var/mob/living/L in J.contents - hit_things) + if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon)) + continue L.adjustFireLoss(20) to_chat(L, "You're hit by the drake's fire breath!") hit_things += L @@ -184,43 +153,86 @@ Difficulty: Medium sleep(1) /mob/living/simple_animal/hostile/megafauna/dragon/proc/triple_swoop() - swoop_attack() - swoop_attack() - swoop_attack() + swoop_attack(swoop_duration = 30) + swoop_attack(swoop_duration = 30) + swoop_attack(swoop_duration = 30) -/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(fire_rain = 0, atom/movable/manual_target) +/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(fire_rain, atom/movable/manual_target, swoop_duration = 40) if(stat || swooping) return - swoop_cooldown = world.time + 200 - var/atom/swoop_target if(manual_target) - swoop_target = manual_target - else - swoop_target = target + target = manual_target + if(!target) + return + swoop_cooldown = world.time + 200 stop_automated_movement = TRUE - swooping = 1 - density = 0 - icon_state = "swoop" + swooping |= SWOOP_DAMAGEABLE + density = FALSE + icon_state = "shadow" visible_message("[src] swoops up high!") - if(prob(50)) - animate(src, pixel_x = 500, pixel_z = 500, time = 10) + + var/negative + var/initial_x = x + if(target.x < initial_x) //if the target's x is lower than ours, swoop to the left + negative = TRUE + else if(target.x > initial_x) + negative = FALSE + else if(target.x == initial_x) //if their x is the same, pick a direction + negative = prob(50) + var/obj/effect/overlay/temp/dragon_flight/F = new /obj/effect/overlay/temp/dragon_flight(loc, negative) + + negative = !negative //invert it for the swoop down later + + var/oldtransform = transform + animate(src, transform = matrix()*0.9, time = 3, easing = BOUNCE_EASING) + for(var/i in 1 to 3) + sleep(1) + if(QDELETED(src)) //we got hit and died, rip us + qdel(F) + return + animate(src, transform = matrix()*0.7, time = 7) + swooping |= SWOOP_INVULNERABLE + sleep(7) + var/list/flame_hit = list() + while(swoop_duration > 0) + if(!target && !FindTarget()) + break //we lost our target while chasing it down and couldn't get a new one + if(swoop_duration < 7) + fire_rain = FALSE //stop raining fire near the end of the swoop + if(loc == get_turf(target)) + if(!fire_rain) + break //we're not spewing fire at our target, slam they + if(isliving(target)) + var/mob/living/L = target + if(L.stat == DEAD) + break //target is dead and we're on em, slam they + if(fire_rain) + new /obj/effect/overlay/temp/target(loc, flame_hit) + forceMove(get_step(src, get_dir(src, target))) + if(loc == get_turf(target)) + if(!fire_rain) + break + if(isliving(target)) + var/mob/living/L = target + if(L.stat == DEAD) + break + var/swoop_speed = 1.5 + swoop_duration -= swoop_speed + sleep(swoop_speed) + + //ensure swoop direction continuity. + if(negative) + if(IsInRange(x, initial_x + 1, initial_x + DRAKE_SWOOP_DIRECTION_CHANGE_RANGE)) + negative = FALSE else - animate(src, pixel_x = -500, pixel_z = 500, time = 10) - sleep(30) - - var/turf/tturf - if(fire_rain) - fire_rain() - + if(IsInRange(x, initial_x - DRAKE_SWOOP_DIRECTION_CHANGE_RANGE, initial_x - 1)) + negative = TRUE + new /obj/effect/overlay/temp/dragon_flight/end(loc, negative) + new /obj/effect/overlay/temp/dragon_swoop(loc) + animate(src, transform = oldtransform, time = 5) + sleep(5) + swooping &= ~SWOOP_INVULNERABLE icon_state = "dragon" - if(swoop_target && !QDELETED(swoop_target) && swoop_target.z == src.z) - tturf = get_turf(swoop_target) - else - tturf = get_turf(src) - forceMove(tturf) - new /obj/effect/overlay/temp/dragon_swoop(tturf) - animate(src, pixel_x = initial(pixel_x), pixel_z = 0, time = 10) - sleep(10) playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1) for(var/mob/living/L in orange(1, src)) if(L.stat) @@ -239,9 +251,9 @@ Difficulty: Medium for(var/mob/M in range(7, src)) shake_camera(M, 15, 1) - stop_automated_movement = FALSE - swooping = 0 - density = 1 + density = TRUE + sleep(1) + swooping &= ~SWOOP_DAMAGEABLE /mob/living/simple_animal/hostile/megafauna/dragon/AltClickOn(atom/movable/A) if(!istype(A)) @@ -249,7 +261,7 @@ Difficulty: Medium if(swoop_cooldown >= world.time) to_chat(src, "You need to wait 20 seconds between swoop attacks!") return - swoop_attack(1, A) + swoop_attack(TRUE, A, 25) /obj/item/device/gps/internal/dragon icon_state = null @@ -257,6 +269,103 @@ Difficulty: Medium desc = "Here there be dragons." invisibility = 100 + +/obj/effect/overlay/temp/fireball + icon = 'icons/obj/wizard.dmi' + icon_state = "fireball" + name = "fireball" + desc = "Get out of the way!" + layer = FLY_LAYER + randomdir = FALSE + duration = 9 + pixel_z = DRAKE_SWOOP_HEIGHT + +/obj/effect/overlay/temp/fireball/Initialize() + . = ..() + animate(src, pixel_z = 0, time = duration) + +/obj/effect/overlay/temp/target + icon = 'icons/mob/actions.dmi' + icon_state = "sniper_zoom" + layer = BELOW_MOB_LAYER + light_range = 2 + duration = 9 + +/obj/effect/overlay/temp/target/ex_act() + return + +/obj/effect/overlay/temp/target/Initialize(mapload, list/flame_hit) + . = ..() + INVOKE_ASYNC(src, .proc/fall, flame_hit) + +/obj/effect/overlay/temp/target/proc/fall(list/flame_hit) + var/turf/T = get_turf(src) + playsound(T,'sound/magic/Fireball.ogg', 80, 1) + new /obj/effect/overlay/temp/fireball(T) + sleep(duration) + if(ismineralturf(T)) + var/turf/closed/mineral/M = T + M.gets_drilled() + playsound(T, "explosion", 80, 1) + new /obj/effect/hotspot(T) + T.hotspot_expose(700, 50, 1) + for(var/mob/living/L in T.contents) + if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon)) + continue + if(!islist(flame_hit) || !flame_hit[L]) + L.adjustFireLoss(40) + to_chat(L, "You're hit by the drake's fire breath!") + flame_hit[L] = TRUE + else + L.adjustFireLoss(10) //if we've already hit them, do way less damage + +/obj/effect/overlay/temp/dragon_swoop + name = "certain death" + desc = "Don't just stand there, move!" + icon = 'icons/effects/96x96.dmi' + icon_state = "landing" + layer = BELOW_MOB_LAYER + pixel_x = -32 + pixel_y = -32 + color = "#FF0000" + duration = 5 + +/obj/effect/overlay/temp/dragon_flight + icon = 'icons/mob/lavaland/dragon.dmi' + icon_state = "dragon" + layer = ABOVE_ALL_MOB_LAYER + pixel_x = -16 + duration = 10 + randomdir = FALSE + +/obj/effect/overlay/temp/dragon_flight/Initialize(mapload, negative) + . = ..() + INVOKE_ASYNC(src, .proc/flight, negative) + +/obj/effect/overlay/temp/dragon_flight/proc/flight(negative) + if(negative) + animate(src, pixel_x = -DRAKE_SWOOP_HEIGHT*0.10, pixel_z = DRAKE_SWOOP_HEIGHT*0.15, time = 3, easing = BOUNCE_EASING) + else + animate(src, pixel_x = DRAKE_SWOOP_HEIGHT*0.10, pixel_z = DRAKE_SWOOP_HEIGHT*0.15, time = 3, easing = BOUNCE_EASING) + sleep(3) + icon_state = "swoop" + if(negative) + animate(src, pixel_x = -DRAKE_SWOOP_HEIGHT, pixel_z = DRAKE_SWOOP_HEIGHT, time = 7) + else + animate(src, pixel_x = DRAKE_SWOOP_HEIGHT, pixel_z = DRAKE_SWOOP_HEIGHT, time = 7) + +/obj/effect/overlay/temp/dragon_flight/end + pixel_x = DRAKE_SWOOP_HEIGHT + pixel_z = DRAKE_SWOOP_HEIGHT + duration = 5 + +/obj/effect/overlay/temp/dragon_flight/end/flight(negative) + if(negative) + pixel_x = -DRAKE_SWOOP_HEIGHT + animate(src, pixel_x = -16, pixel_z = 0, time = 5) + else + animate(src, pixel_x = -16, pixel_z = 0, time = 5) + /mob/living/simple_animal/hostile/megafauna/dragon/lesser name = "lesser ash drake" maxHealth = 200 diff --git a/icons/mob/lavaland/dragon.dmi b/icons/mob/lavaland/dragon.dmi index 7e44b775de8c48a8d25788af45339c727c221b6f..911d7288d122f08e721231810d02b48fc91f4777 100644 GIT binary patch delta 13511 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 delta 12361 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 Date: Wed, 26 Apr 2017 10:11:34 -0500 Subject: [PATCH 07/15] Automatic changelog generation for PR #571 [ci skip] --- html/changelogs/AutoChangeLog-pr-571.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-571.yml diff --git a/html/changelogs/AutoChangeLog-pr-571.yml b/html/changelogs/AutoChangeLog-pr-571.yml new file mode 100644 index 0000000000..2535c774d8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-571.yml @@ -0,0 +1,5 @@ +author: "Joan" +delete-after: True +changes: + - tweak: "Ash Drake swoops no longer teleport the Ash Drake to your position. +balance: Some other tweaks to Ash Drake attacks and patterns; discover these yourself!" From c5eeb2de678a980208870c43e8c2947a6f2959c7 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 10:11:47 -0500 Subject: [PATCH 08/15] Revert "Ghosts call Moved() after Move() (#26183)" (#510) --- code/modules/mob/dead/observer/observer.dm | 29 +++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 7946d67d10..2c5b064137 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -272,24 +272,25 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/Move(NewLoc, direct) if(updatedir) - setDir(direct)//only update dir if we actually need it, so overlays won't spin on base sprites that don't have directions of their own - var/oldloc = loc - + setDir(direct )//only update dir if we actually need it, so overlays won't spin on base sprites that don't have directions of their own if(NewLoc) loc = NewLoc + for(var/obj/effect/step_trigger/S in NewLoc) + S.Crossed(src) update_parallax_contents() - else - loc = get_turf(src) //Get out of closets and such as a ghost - if((direct & NORTH) && y < world.maxy) - y++ - else if((direct & SOUTH) && y > 1) - y-- - if((direct & EAST) && x < world.maxx) - x++ - else if((direct & WEST) && x > 1) - x-- + return + loc = get_turf(src) //Get out of closets and such as a ghost + if((direct & NORTH) && y < world.maxy) + y++ + else if((direct & SOUTH) && y > 1) + y-- + if((direct & EAST) && x < world.maxx) + x++ + else if((direct & WEST) && x > 1) + x-- - Moved(oldloc, direct) + for(var/obj/effect/step_trigger/S in locate(x, y, z)) //<-- this is dumb + S.Crossed(src) /mob/dead/observer/is_active() return 0 From bb97f09b7450212e0072b3d5f4d2cfa12b0ba0c0 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Wed, 26 Apr 2017 10:15:44 -0500 Subject: [PATCH 09/15] Update window.dm --- code/game/objects/structures/window.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 0b2563a7b0..d5027a0c75 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -18,7 +18,7 @@ var/fulltile = 0 var/glass_type = /obj/item/stack/sheet/glass var/glass_amount = 1 - var/static/mutable_appearance/crack_overlay = mutable_appearance('icons/obj/structures.dmi') + var/mutable_appearance/crack_overlay var/list/debris = list() can_be_unanchored = 1 resistance_flags = ACID_PROOF @@ -377,10 +377,10 @@ if(smooth) queue_smooth(src) - cut_overlays() + cut_overlay(crack_overlay) if(ratio > 75) return - crack_overlay.icon_state = "damage[ratio]" + crack_overlay = mutable_appearance('icons/obj/structures.dmi', "damage[ratio]", -(layer+0.1)) add_overlay(crack_overlay) /obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) From 328ddaba1f75f066aa04b50e4f51f1c76e42b150 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Wed, 26 Apr 2017 10:15:54 -0500 Subject: [PATCH 10/15] Delete window.dm.rej --- code/game/objects/structures/window.dm.rej | 23 ---------------------- 1 file changed, 23 deletions(-) delete mode 100644 code/game/objects/structures/window.dm.rej diff --git a/code/game/objects/structures/window.dm.rej b/code/game/objects/structures/window.dm.rej deleted file mode 100644 index 39a6d57678..0000000000 --- a/code/game/objects/structures/window.dm.rej +++ /dev/null @@ -1,23 +0,0 @@ -diff a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm (rejected hunks) -@@ -18,7 +18,7 @@ - var/fulltile = 0 - var/glass_type = /obj/item/stack/sheet/glass - var/glass_amount = 1 -- var/static/mutable_appearance/crack_overlay = mutable_appearance('icons/obj/structures.dmi') -+ var/mutable_appearance/crack_overlay - var/list/debris = list() - can_be_unanchored = 1 - resistance_flags = ACID_PROOF -@@ -377,10 +377,10 @@ - if(smooth) - queue_smooth(src) - -- cut_overlays() -+ cut_overlay(crack_overlay) - if(ratio > 75) - return -- crack_overlay.icon_state = "damage[ratio]" -+ crack_overlay = mutable_appearance('icons/obj/structures.dmi', "damage[ratio]", -(layer+0.1)) - add_overlay(crack_overlay) - - /obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) From 8ec4cbbb9f9d533e7935b1dfcacdbb2098bf9de8 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Wed, 26 Apr 2017 10:37:57 -0500 Subject: [PATCH 11/15] Fixes carelessness. (#577) * Update hud.dm * Delete hud.dm.rej * Update alternate_appearance.dm * Delete alternate_appearance.dm.rej * Delete mob.dm.rej * Update mob.dm --- code/datums/hud.dm | 174 +++++++++++++------------- code/datums/hud.dm.rej | 10 -- code/game/alternate_appearance.dm | 13 +- code/game/alternate_appearance.dm.rej | 19 --- code/modules/mob/mob.dm | 2 + code/modules/mob/mob.dm.rej | 10 -- 6 files changed, 95 insertions(+), 133 deletions(-) delete mode 100644 code/datums/hud.dm.rej delete mode 100644 code/game/alternate_appearance.dm.rej delete mode 100644 code/modules/mob/mob.dm.rej diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 2b12c42452..f9444898ce 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -1,93 +1,93 @@ -/* HUD DATUMS */ - -//GLOBAL HUD LIST -GLOBAL_LIST_INIT(huds, list( - DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(), - DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(), - DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(), - DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), - DATA_HUD_DIAGNOSTIC = new/datum/atom_hud/data/diagnostic(), - ANTAG_HUD_CULT = new/datum/atom_hud/antag(), - ANTAG_HUD_REV = new/datum/atom_hud/antag(), - ANTAG_HUD_OPS = new/datum/atom_hud/antag(), - ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), - ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(), - ANTAG_HUD_TRAITOR = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_DEVIL = new/datum/atom_hud/antag(), - ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(), - )) - -/datum/atom_hud - var/list/atom/hudatoms = list() //list of all atoms which display this hud - var/list/mob/hudusers = list() //list with all mobs who can see the hud - var/list/hud_icons = list() //these will be the indexes for the atom's hud_list - -/datum/atom_hud/proc/remove_hud_from(mob/M) - if(!M) - return - if(src in M.permanent_huds) - return - for(var/atom/A in hudatoms) - remove_from_single_hud(M, A) - hudusers -= M - -/datum/atom_hud/proc/remove_from_hud(atom/A) - if(!A) +/* HUD DATUMS */ + +//GLOBAL HUD LIST +GLOBAL_LIST_INIT(huds, list( + DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(), + DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(), + DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(), + DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), + DATA_HUD_DIAGNOSTIC = new/datum/atom_hud/data/diagnostic(), + ANTAG_HUD_CULT = new/datum/atom_hud/antag(), + ANTAG_HUD_REV = new/datum/atom_hud/antag(), + ANTAG_HUD_OPS = new/datum/atom_hud/antag(), + ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), + ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(), + ANTAG_HUD_TRAITOR = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_DEVIL = new/datum/atom_hud/antag(), + ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(), + )) + +/datum/atom_hud + var/list/atom/hudatoms = list() //list of all atoms which display this hud + var/list/mob/hudusers = list() //list with all mobs who can see the hud + var/list/hud_icons = list() //these will be the indexes for the atom's hud_list + +/datum/atom_hud/proc/remove_hud_from(mob/M) + if(!M) + return + if(src in M.permanent_huds) + return + for(var/atom/A in hudatoms) + remove_from_single_hud(M, A) + hudusers -= M + +/datum/atom_hud/proc/remove_from_hud(atom/A) + if(!A) return FALSE - for(var/mob/M in hudusers) - remove_from_single_hud(M, A) - hudatoms -= A + for(var/mob/M in hudusers) + remove_from_single_hud(M, A) + hudatoms -= A return TRUE - -/datum/atom_hud/proc/remove_from_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client - if(!M || !M.client || !A) - return - for(var/i in hud_icons) - M.client.images -= A.hud_list[i] - -/datum/atom_hud/proc/add_hud_to(mob/M) - if(!M) - return + +/datum/atom_hud/proc/remove_from_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client + if(!M || !M.client || !A) + return + for(var/i in hud_icons) + M.client.images -= A.hud_list[i] + +/datum/atom_hud/proc/add_hud_to(mob/M) + if(!M) + return hudusers[M] = TRUE - for(var/atom/A in hudatoms) - add_to_single_hud(M, A) - -/datum/atom_hud/proc/add_to_hud(atom/A) - if(!A) + for(var/atom/A in hudatoms) + add_to_single_hud(M, A) + +/datum/atom_hud/proc/add_to_hud(atom/A) + if(!A) return FALSE - hudatoms |= A - for(var/mob/M in hudusers) - add_to_single_hud(M, A) + hudatoms |= A + for(var/mob/M in hudusers) + add_to_single_hud(M, A) return TRUE - -/datum/atom_hud/proc/add_to_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client - if(!M || !M.client || !A) - return - for(var/i in hud_icons) - if(A.hud_list[i]) - M.client.images |= A.hud_list[i] - -//MOB PROCS -/mob/proc/reload_huds() - var/gang_huds = list() - if(SSticker.mode) - for(var/datum/gang/G in SSticker.mode.gangs) - gang_huds += G.ganghud - + +/datum/atom_hud/proc/add_to_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client + if(!M || !M.client || !A) + return + for(var/i in hud_icons) + if(A.hud_list[i]) + M.client.images |= A.hud_list[i] + +//MOB PROCS +/mob/proc/reload_huds() + var/gang_huds = list() + if(SSticker.mode) + for(var/datum/gang/G in SSticker.mode.gangs) + gang_huds += G.ganghud + for(var/datum/atom_hud/hud in (GLOB.huds|gang_huds|GLOB.active_alternate_appearances)) - if(hud.hudusers[src]) - hud.add_hud_to(src) - -/mob/dead/new_player/reload_huds() - return - -/mob/proc/add_click_catcher() - client.screen += client.void - -/mob/dead/new_player/add_click_catcher() - return + if(hud && hud.hudusers[src]) + hud.add_hud_to(src) + +/mob/dead/new_player/reload_huds() + return + +/mob/proc/add_click_catcher() + client.screen += client.void + +/mob/dead/new_player/add_click_catcher() + return diff --git a/code/datums/hud.dm.rej b/code/datums/hud.dm.rej deleted file mode 100644 index 3696e8b8fe..0000000000 --- a/code/datums/hud.dm.rej +++ /dev/null @@ -1,10 +0,0 @@ -diff a/code/datums/hud.dm b/code/datums/hud.dm (rejected hunks) -@@ -80,7 +80,7 @@ GLOBAL_LIST_INIT(huds, list( - gang_huds += G.ganghud - - for(var/datum/atom_hud/hud in (GLOB.huds|gang_huds|GLOB.active_alternate_appearances)) -- if(hud.hudusers[src]) -+ if(hud && hud.hudusers[src]) - hud.add_hud_to(src) - - /mob/dead/new_player/reload_huds() diff --git a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm index ac23d61e7f..ce2529890b 100644 --- a/code/game/alternate_appearance.dm +++ b/code/game/alternate_appearance.dm @@ -29,13 +29,12 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances) appearance_key = key /datum/atom_hud/alternate_appearance/Destroy() - if(!QDELETED(src)) - for(var/v in hudusers) - remove_hud_from(v) - for(var/v in hudatoms) - remove_from_hud(v) - GLOB.active_alternate_appearances -= src - return ..() + for(var/v in hudusers) + remove_hud_from(v) + for(var/v in hudatoms) + remove_from_hud(v) + GLOB.active_alternate_appearances -= src + return ..() /datum/atom_hud/alternate_appearance/proc/onNewMob(mob/M) if(mobShouldSee(M)) diff --git a/code/game/alternate_appearance.dm.rej b/code/game/alternate_appearance.dm.rej deleted file mode 100644 index 52f96ceabd..0000000000 --- a/code/game/alternate_appearance.dm.rej +++ /dev/null @@ -1,19 +0,0 @@ -diff a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm (rejected hunks) -@@ -29,12 +29,11 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances) - appearance_key = key - - /datum/atom_hud/alternate_appearance/Destroy() -- if(!QDELETED(src)) -- for(var/v in hudusers) -- remove_hud_from(v) -- for(var/v in hudatoms) -- remove_from_hud(v) -- GLOB.active_alternate_appearances -= src -+ for(var/v in hudusers) -+ remove_hud_from(v) -+ for(var/v in hudatoms) -+ remove_from_hud(v) -+ GLOB.active_alternate_appearances -= src - return ..() - - /datum/atom_hud/alternate_appearance/proc/onNewMob(mob/M) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 95e034fd96..4712594179 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -30,6 +30,8 @@ can_ride_typecache = typecacheof(can_ride_typecache) hook_vr("mob_new",list(src)) for(var/v in GLOB.active_alternate_appearances) + if(!v) + continue var/datum/atom_hud/alternate_appearance/AA = v AA.onNewMob(src) ..() diff --git a/code/modules/mob/mob.dm.rej b/code/modules/mob/mob.dm.rej deleted file mode 100644 index cff44187b0..0000000000 --- a/code/modules/mob/mob.dm.rej +++ /dev/null @@ -1,10 +0,0 @@ -diff a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm (rejected hunks) -@@ -29,6 +29,8 @@ - prepare_huds() - can_ride_typecache = typecacheof(can_ride_typecache) - for(var/v in GLOB.active_alternate_appearances) -+ if(!v) -+ continue - var/datum/atom_hud/alternate_appearance/AA = v - AA.onNewMob(src) - ..() From 3d2f91d0c7c5cf58e91b6628451794da6d9a0aba Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 11:08:30 -0500 Subject: [PATCH 12/15] Removes a lavaland_surface_ww_vault.dmm because its just bad. (#536) --- _maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm | 1 + code/datums/ruins/lavaland.dm | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm index 2890b4954b..ab0173231e 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm @@ -131,6 +131,7 @@ }, /turf/open/floor/engine/cult{ baseturf = /turf/open/floor/plating/lava/smooth; + }, /obj/structure/fans/tiny/invisible, /area/ruin/powered) diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index 12df20891f..3a54db4e0a 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -129,13 +129,6 @@ suffix = "lavaland_surface_ufo_crash.dmm" cost = 5 -/datum/map_template/ruin/lavaland/ww_vault - name = "Wishgranter Vault" - id = "ww-vault" - description = "Scrawled on the large double doors is both a message and a warning: 'meat grinder requires sacri...'. You're not so sure about this anymore." - suffix = "lavaland_surface_ww_vault.dmm" - cost = 20 - /datum/map_template/ruin/lavaland/xeno_nest name = "Xenomorph Nest" id = "xeno-nest" From ec2da50fbc2a0b664929eeb7afe48d3cb1663fca Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 11:08:31 -0500 Subject: [PATCH 13/15] Automatic changelog generation for PR #536 [ci skip] --- html/changelogs/AutoChangeLog-pr-536.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-536.yml diff --git a/html/changelogs/AutoChangeLog-pr-536.yml b/html/changelogs/AutoChangeLog-pr-536.yml new file mode 100644 index 0000000000..cc711de25c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-536.yml @@ -0,0 +1,4 @@ +author: "Jalleo" +delete-after: True +changes: + - rscdel: "WW_maze from lavaland has been removed it wasnt that good really anyhow" From 87ce25df9b07ec6891c316d65a802f22f20538e7 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 11:09:00 -0500 Subject: [PATCH 14/15] Removes a unused chem (#576) --- .../objects/items/weapons/tanks/watertank.dm | 7 +--- .../chemistry/reagents/medicine_reagents.dm | 38 ------------------- 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm index 265e6bb2e5..3a63757157 100644 --- a/code/game/objects/items/weapons/tanks/watertank.dm +++ b/code/game/objects/items/weapons/tanks/watertank.dm @@ -432,11 +432,6 @@ update_filling() user.update_inv_back() //for overlays update -/obj/item/weapon/reagent_containers/chemtank/stim/New() - ..() - reagents.add_reagent("stimulants_longterm", 300) - update_filling() - //Operator backpack spray /obj/item/weapon/watertank/operator name = "backpack water tank" @@ -468,4 +463,4 @@ possible_transfer_amounts = list(75,100,150) /obj/item/weapon/watertank/operator/make_noz() - return new /obj/item/weapon/reagent_containers/spray/mister/operator(src) \ No newline at end of file + return new /obj/item/weapon/reagent_containers/spray/mister/operator(src) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index dee5b7e68a..aa913ba8f0 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -867,44 +867,6 @@ . = 1 ..() -/datum/reagent/medicine/stimulants/longterm - name = "Stimulants" - id = "stimulants_longterm" - description = "Increases stun resistance and movement speed in addition to restoring minor damage and weakness. Highly addictive." - color = "#78008C" - metabolization_rate = 2 * REAGENTS_METABOLISM - overdose_threshold = 0 - addiction_threshold = 5 - -/datum/reagent/medicine/stimulants/longterm/addiction_act_stage1(mob/living/M) - M.adjustToxLoss(5*REM, 0) - M.adjustStaminaLoss(5*REM, 0) - ..() - . = 1 - -/datum/reagent/medicine/stimulants/longterm/addiction_act_stage2(mob/living/M) - M.adjustToxLoss(6*REM, 0) - M.adjustStaminaLoss(5*REM, 0) - M.Stun(2, 0) - ..() - . = 1 - -/datum/reagent/medicine/stimulants/longterm/addiction_act_stage3(mob/living/M) - M.adjustToxLoss(7*REM, 0) - M.adjustStaminaLoss(5*REM, 0) - M.adjustBrainLoss(1*REM) - M.Stun(2, 0) - ..() - . = 1 - -/datum/reagent/medicine/stimulants/longterm/addiction_act_stage4(mob/living/M) - M.adjustToxLoss(8*REM, 0) - M.adjustStaminaLoss(5*REM, 0) - M.adjustBrainLoss(2*REM) - M.Stun(2, 0) - ..() - . = 1 - /datum/reagent/medicine/insulin name = "Insulin" id = "insulin" From e7df2bc14ac703a6e5743b86a7c350e2c7baf584 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 26 Apr 2017 11:13:41 -0500 Subject: [PATCH 15/15] [MIRROR] Minor refactors (#515) * Minor refactors * Update client_procs.dm * Delete client_procs.dm.rej --- code/game/atoms.dm | 4 ++++ code/game/objects/objs.dm | 8 ------- code/game/objects/structures/morgue.dm | 6 ++--- code/modules/client/client_procs.dm | 30 +++++++++++++++++++++++- code/modules/mob/living/login.dm | 2 +- code/modules/mob/living/silicon/login.dm | 2 +- code/modules/mob/login.dm | 10 ++++---- code/modules/mob/logout.dm | 30 +++--------------------- 8 files changed, 44 insertions(+), 48 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 7f5615cfa7..fda74c2ac8 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -495,6 +495,10 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons) /atom/proc/mech_melee_attack(obj/mecha/M) return +//If a mob logouts/logins in side of an object you can use this proc +/atom/proc/on_log(login) + if(loc) + loc.on_log(login) /* diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index f297662c2d..4c61b09ca3 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -165,14 +165,6 @@ /obj/proc/hide(h) return -//If a mob logouts/logins in side of an object you can use this proc -/obj/proc/on_log() - ..() - if(isobj(loc)) - var/obj/Loc=loc - Loc.on_log() - - /obj/singularity_pull(S, current_size) if(!anchored || current_size >= STAGE_FIVE) step_towards(src,S) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index a13858296a..39ff2a7da9 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -24,9 +24,6 @@ var/locked = 0 var/opendir = SOUTH -/obj/structure/bodycontainer/New() - ..() - /obj/structure/bodycontainer/Destroy() open() if(connected) @@ -34,7 +31,8 @@ connected = null return ..() -/obj/structure/bodycontainer/on_log() +/obj/structure/bodycontainer/on_log(login) + ..() update_icon() /obj/structure/bodycontainer/update_icon() diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 08f240ac31..4f6642f051 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -370,6 +370,34 @@ GLOBAL_LIST(external_rsc_urls) adminGreet(1) holder.owner = null GLOB.admins -= src + + if (!GLOB.admins.len && SSticker.current_state == GAME_STATE_PLAYING) //Only report this stuff if we are currently playing. + if(!GLOB.admins.len) //Apparently the admin logging out is no longer an admin at this point, so we have to check this towards 0 and not towards 1. Awell. + var/cheesy_message = pick( + "I have no admins online!",\ + "I'm all alone... :(",\ + "I'm feeling lonely. :(",\ + "I'm so lonely. :(",\ + "Why does nobody love me? :(",\ + "I want a man. :(",\ + "Where has everyone gone?",\ + "I need a hug. :(",\ + "Someone come hold me. :(",\ + "I need someone on me :(",\ + "What happened? Where has everyone gone?",\ + "My nipples are so stiff, but Zelda ain't here. :(",\ + "Leon senpai, play more Spessmans. :(",\ + "If only Serdy were here...",\ + "Panic bunker can't keep my love for you out.",\ + "Cebu needs to Awoo herself back into my heart.",\ + "I don't even have a Turry to snuggle viciously here.",\ + "MOM, WHERE ARE YOU???",\ + "It's a beautiful day outside. Birds are singing, flowers are blooming. On days like this...kids like you...SHOULD BE BURNING IN HELL.",\ + "Sometimes when I have sex, I think about putting an entire peanut butter and jelly sandwich in the VCR.",\ + "Forever alone :("\ + ) + + send2irc("Server", "[cheesy_message] (No admins online)") GLOB.ahelp_tickets.ClientLogout(src) GLOB.directory -= ckey @@ -613,4 +641,4 @@ GLOBAL_LIST(external_rsc_urls) if (isnull(new_size)) CRASH("change_view called without argument.") - view = new_size \ No newline at end of file + view = new_size diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index 6365ab04f4..94b26fd229 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -5,7 +5,7 @@ mind.show_memory(src, 0) //Round specific stuff - if(SSticker && SSticker.mode) + if(SSticker.mode) switch(SSticker.mode.name) if("sandbox") CanBuild() diff --git a/code/modules/mob/living/silicon/login.dm b/code/modules/mob/living/silicon/login.dm index 38d83af1a4..e9efce3fa6 100644 --- a/code/modules/mob/living/silicon/login.dm +++ b/code/modules/mob/living/silicon/login.dm @@ -1,5 +1,5 @@ /mob/living/silicon/Login() - if(mind && SSticker && SSticker.mode) + if(mind && SSticker.mode) SSticker.mode.remove_cultist(mind, 0, 0) SSticker.mode.remove_revolutionary(mind, 0) SSticker.mode.remove_gangster(mind, remove_bosses=1) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 9f439d8372..90a331f03c 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -15,13 +15,11 @@ next_move = 1 ..() - if (key != client.key) - key = client.key + reset_perspective(loc) - if(isobj(loc)) - var/obj/Loc=loc - Loc.on_log() + if(loc) + loc.on_log(TRUE) //readd this mob's HUDs (antag, med, etc) reload_huds() @@ -41,4 +39,4 @@ if(client) client.click_intercept = null - client.view = world.view // Resets the client.view in case it was changed. \ No newline at end of file + client.view = world.view // Resets the client.view in case it was changed. \ No newline at end of file diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index b3d708eee9..770ec01d42 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -2,34 +2,10 @@ SStgui.on_logout(src) unset_machine() GLOB.player_list -= src - if(GLOB.admin_datums[src.ckey]) - if (SSticker && SSticker.current_state == GAME_STATE_PLAYING) //Only report this stuff if we are currently playing. - var/admins_number = GLOB.admins.len - if(admins_number == 0) //Apparently the admin logging out is no longer an admin at this point, so we have to check this towards 0 and not towards 1. Awell. - var/cheesy_message = pick( list( \ - "I have no admins online!",\ - "I'm all alone :(",\ - "I'm feeling lonely :(",\ - "I'm so lonely :(",\ - "Why does nobody love me? :(",\ - "I want a man :(",\ - "Where has everyone gone?",\ - "I need a hug :(",\ - "Someone come hold me :(",\ - "I need someone on me :(",\ - "What happened? Where has everyone gone?",\ - "Forever alone :("\ - ) ) - if(cheesy_message) - cheesy_message += " (No admins online)" - - - send2irc("Server", "[cheesy_message]") ..() - if(isobj(loc)) - var/obj/Loc=loc - Loc.on_log() + if(loc) + loc.on_log(FALSE) - return 1 \ No newline at end of file + return TRUE \ No newline at end of file