From b69e24086a642299d5fbfa230a6e9bbc8e521008 Mon Sep 17 00:00:00 2001 From: Chompstation Bot Date: Fri, 18 Jun 2021 18:02:23 +0000 Subject: [PATCH] 6 fixes --- code/datums/chat_message.dm | 3 + code/datums/components/overlay_lighting.dm | 518 ++++++++++++++++++ code/game/objects/effects/misc.dm | 90 ++- code/game/objects/effects/overlays.dm | 105 ++++ code/modules/artifice/telecube.dm | 2 +- code/modules/awaymissions/gateway.dm | 108 ++++ code/modules/clothing/spacesuits/rig/rig.dm | 4 +- code/modules/clothing/spacesuits/void/void.dm | 4 +- code/modules/food/food/snacks.dm | 60 +- 9 files changed, 859 insertions(+), 35 deletions(-) create mode 100644 code/datums/components/overlay_lighting.dm diff --git a/code/datums/chat_message.dm b/code/datums/chat_message.dm index a625d0cd58..ae17f21e2d 100644 --- a/code/datums/chat_message.dm +++ b/code/datums/chat_message.dm @@ -196,6 +196,9 @@ var/list/runechat_image_cache = list() message.maptext_y = message_loc.runechat_y_offset(msgwidth, mheight) message.maptext = complete_text + if(!owner) + qdel(src) + return if(owner.contains(target)) // Special case, holding an atom speaking (pAI, recorder...) message.plane = PLANE_PLAYER_HUD_ABOVE diff --git a/code/datums/components/overlay_lighting.dm b/code/datums/components/overlay_lighting.dm new file mode 100644 index 0000000000..a037e7fab1 --- /dev/null +++ b/code/datums/components/overlay_lighting.dm @@ -0,0 +1,518 @@ +///For switchable lights, is it on and currently emitting light? +#define LIGHTING_ON (1<<0) +///Is the parent attached to something else, its loc? Then we need to keep an eye of this. +#define LIGHTING_ATTACHED (1<<1) + +#define GET_PARENT (parent_attached_to || parent) + +#define GET_LIGHT_SOURCE (directional_atom || current_holder) + +#define SHORT_CAST 2 + +/** + * Movable atom overlay-based lighting component. + * + * * Component works by applying a visual object to the parent target. + * + * * The component tracks the parent's loc to determine the current_holder. + * * The current_holder is either the parent or its loc, whichever is on a turf. If none, then the current_holder is null and the light is not visible. + * + * * Lighting works at its base by applying a dark overlay and "cutting" said darkness with light, adding (possibly colored) transparency. + * * This component uses the visible_mask visual object to apply said light mask on the darkness. + * + * * The main limitation of this system is that it uses a limited number of pre-baked geometrical shapes, but for most uses it does the job. + * + * * Another limitation is for big lights: you only see the light if you see the object emiting it. + * * For small objects this is good (you can't see them behind a wall), but for big ones this quickly becomes prety clumsy. +*/ +/datum/component/overlay_lighting + ///How far the light reaches, float. + var/range = 1 + ///Ceiling of range, integer without decimal entries. + var/lumcount_range = 0 + ///How much this light affects the dynamic_lumcount of turfs. + var/lum_power = 0.5 + ///Transparency value. + var/set_alpha = 0 + ///For light sources that can be turned on and off. + var/overlay_lighting_flags = NONE + + ///Cache of the possible light overlays, according to size. + var/static/list/light_overlays = list( + "32" = 'icons/effects/light_overlays/light_32.dmi', + "64" = 'icons/effects/light_overlays/light_64.dmi', + "96" = 'icons/effects/light_overlays/light_96.dmi', + "128" = 'icons/effects/light_overlays/light_128.dmi', + "160" = 'icons/effects/light_overlays/light_160.dmi', + "192" = 'icons/effects/light_overlays/light_192.dmi', + "224" = 'icons/effects/light_overlays/light_224.dmi', + "256" = 'icons/effects/light_overlays/light_256.dmi', + "288" = 'icons/effects/light_overlays/light_288.dmi', + "320" = 'icons/effects/light_overlays/light_320.dmi', + "352" = 'icons/effects/light_overlays/light_352.dmi', + ) + + ///Overlay effect to cut into the darkness and provide light. + var/obj/effect/overlay/light_visible/visible_mask + ///Lazy list to track the turfs being affected by our light, to determine their visibility. + var/list/turf/affected_turfs + ///Movable atom currently holding the light. Parent might be a flashlight, for example, but that might be held by a mob or something else. + var/atom/movable/current_holder + ///Movable atom the parent is attached to. For example, a flashlight into a helmet or gun. We'll need to track the thing the parent is attached to as if it were the parent itself. + var/atom/movable/parent_attached_to + ///Whether we're a directional light + var/directional + ///Abstractional atom for directional light, we move this around to make the directional effect + var/obj/effect/abstract/directional_lighting/directional_atom + ///A cone overlay for directional light, it's alpha and color are dependant on the light + var/obj/effect/overlay/light_cone/cone + ///Current tracked direction for the directional cast behaviour + var/current_direction + ///Cast range for the directional cast (how far away the atom is moved) + var/cast_range = 2 + ///Cone offset X hint from atom, used when facing south, inverted when facing north + var/cone_hint_x + ///Cone offset Y hint from atom, when facing east/west, ignored for north/south (uses 16 in those cases) + var/cone_hint_y + + +/datum/component/overlay_lighting/Initialize(_range, _power, _color, starts_on, is_directional) + if(!ismovable(parent)) + return COMPONENT_INCOMPATIBLE + + var/atom/movable/movable_parent = parent + if(movable_parent.light_system != MOVABLE_LIGHT && movable_parent.light_system != MOVABLE_LIGHT_DIRECTIONAL) + stack_trace("[type] added to [parent], with [movable_parent.light_system] value for the light_system var. Use [MOVABLE_LIGHT] or [MOVABLE_LIGHT_DIRECTIONAL] instead.") + return COMPONENT_INCOMPATIBLE + + . = ..() + + visible_mask = new() + if(is_directional) + directional = TRUE + directional_atom = new() + cone = new() + cone_hint_x = movable_parent.light_cone_x_offset + cone_hint_y = movable_parent.light_cone_y_offset + cone.transform = cone.transform.Translate(-32, -32) + set_direction(movable_parent.dir) + if(!isnull(_range)) + movable_parent.set_light_range(_range) + set_range(parent, movable_parent.light_range) + if(!isnull(_power)) + movable_parent.set_light_power(_power) + set_power(parent, movable_parent.light_power) + if(!isnull(_color)) + movable_parent.set_light_color(_color) + set_color(parent, movable_parent.light_color) + if(!isnull(starts_on)) + movable_parent.set_light_on(starts_on) + + +/datum/component/overlay_lighting/RegisterWithParent() + . = ..() + if(directional) + RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/on_parent_dir_change) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/on_parent_moved) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_RANGE, .proc/set_range) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_POWER, .proc/set_power) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_COLOR, .proc/set_color) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_ON, .proc/on_toggle) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_FLAGS, .proc/on_light_flags_change) + RegisterSignal(parent, COMSIG_ATOM_USED_IN_CRAFT, .proc/on_parent_crafted) + RegisterSignal(parent, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater) + var/atom/movable/movable_parent = parent + if(movable_parent.light_flags & LIGHT_ATTACHED) + overlay_lighting_flags |= LIGHTING_ATTACHED + set_parent_attached_to(ismovable(movable_parent.loc) ? movable_parent.loc : null) + check_holder() + if(movable_parent.light_on) + turn_on() + + +/datum/component/overlay_lighting/UnregisterFromParent() + overlay_lighting_flags &= ~LIGHTING_ATTACHED + set_parent_attached_to(null) + set_holder(null) + clean_old_turfs() + UnregisterSignal(parent, list( + COMSIG_MOVABLE_MOVED, + COMSIG_ATOM_UPDATE_LIGHT_RANGE, + COMSIG_ATOM_UPDATE_LIGHT_POWER, + COMSIG_ATOM_UPDATE_LIGHT_COLOR, + COMSIG_ATOM_UPDATE_LIGHT_ON, + COMSIG_ATOM_UPDATE_LIGHT_FLAGS, + COMSIG_ATOM_USED_IN_CRAFT, + COMSIG_LIGHT_EATER_QUEUE, + )) + if(directional) + UnregisterSignal(parent, COMSIG_ATOM_DIR_CHANGE) + if(overlay_lighting_flags & LIGHTING_ON) + turn_off() + return ..() + + +/datum/component/overlay_lighting/Destroy() + set_parent_attached_to(null) + set_holder(null) + clean_old_turfs() + + qdel(visible_mask, TRUE) + visible_mask = null + + if(directional) + qdel(directional_atom, TRUE) + directional_atom = null + + qdel(cone, TRUE) + cone = null + + return ..() + + +///Clears the affected_turfs lazylist, removing from its contents the effects of being near the light. +/datum/component/overlay_lighting/proc/clean_old_turfs() + for(var/t in affected_turfs) + var/turf/lit_turf = t + lit_turf.dynamic_lumcount -= lum_power + affected_turfs = null + + +///Populates the affected_turfs lazylist, adding to its contents the effects of being near the light. +/datum/component/overlay_lighting/proc/get_new_turfs() + if(!current_holder) + return + var/atom/movable/light_source = GET_LIGHT_SOURCE + for(var/turf/lit_turf in view(lumcount_range, get_turf(light_source))) + lit_turf.dynamic_lumcount += lum_power + LAZYADD(affected_turfs, lit_turf) + + +///Clears the old affected turfs and populates the new ones. +/datum/component/overlay_lighting/proc/make_luminosity_update() + clean_old_turfs() + if(!isturf(current_holder?.loc)) + return + if(directional) + cast_directional_light() + get_new_turfs() + + +///Adds the luminosity and source for the afected movable atoms to keep track of their visibility. +/datum/component/overlay_lighting/proc/add_dynamic_lumi() + var/atom/movable/light_source = GET_LIGHT_SOURCE + LAZYSET(light_source.affected_dynamic_lights, src, lumcount_range + 1) + light_source.vis_contents += visible_mask + light_source.update_dynamic_luminosity() + if(directional) + current_holder.vis_contents += cone + +///Removes the luminosity and source for the afected movable atoms to keep track of their visibility. +/datum/component/overlay_lighting/proc/remove_dynamic_lumi() + var/atom/movable/light_source = GET_LIGHT_SOURCE + LAZYREMOVE(light_source.affected_dynamic_lights, src) + light_source.vis_contents -= visible_mask + light_source.update_dynamic_luminosity() + if(directional) + current_holder.vis_contents -= cone + directional_atom.moveToNullspace() + +///Called to change the value of parent_attached_to. +/datum/component/overlay_lighting/proc/set_parent_attached_to(atom/movable/new_parent_attached_to) + if(new_parent_attached_to == parent_attached_to) + return + + . = parent_attached_to + parent_attached_to = new_parent_attached_to + if(.) + var/atom/movable/old_parent_attached_to = . + UnregisterSignal(old_parent_attached_to, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED, COMSIG_LIGHT_EATER_QUEUE)) + if(old_parent_attached_to == current_holder) + RegisterSignal(old_parent_attached_to, COMSIG_PARENT_QDELETING, .proc/on_holder_qdel) + RegisterSignal(old_parent_attached_to, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved) + RegisterSignal(old_parent_attached_to, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater) + if(parent_attached_to) + if(parent_attached_to == current_holder) + UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED, COMSIG_LIGHT_EATER_QUEUE)) + RegisterSignal(parent_attached_to, COMSIG_PARENT_QDELETING, .proc/on_parent_attached_to_qdel) + RegisterSignal(parent_attached_to, COMSIG_MOVABLE_MOVED, .proc/on_parent_attached_to_moved) + RegisterSignal(parent_attached_to, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater) + check_holder() + + +///Called to change the value of current_holder. +/datum/component/overlay_lighting/proc/set_holder(atom/movable/new_holder) + if(new_holder == current_holder) + return + if(current_holder) + if(current_holder != parent && current_holder != parent_attached_to) + UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED, COMSIG_LIGHT_EATER_QUEUE)) + if(directional) + UnregisterSignal(current_holder, COMSIG_ATOM_DIR_CHANGE) + if(overlay_lighting_flags & LIGHTING_ON) + remove_dynamic_lumi() + current_holder = new_holder + if(new_holder == null) + clean_old_turfs() + return + if(new_holder != parent && new_holder != parent_attached_to) + RegisterSignal(new_holder, COMSIG_PARENT_QDELETING, .proc/on_holder_qdel) + RegisterSignal(new_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved) + RegisterSignal(new_holder, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater) + if(directional) + RegisterSignal(new_holder, COMSIG_ATOM_DIR_CHANGE, .proc/on_holder_dir_change) + if(overlay_lighting_flags & LIGHTING_ON) + make_luminosity_update() + add_dynamic_lumi() + + +///Used to determine the new valid current_holder from the parent's loc. +/datum/component/overlay_lighting/proc/check_holder() + var/atom/movable/movable_parent = GET_PARENT + if(isturf(movable_parent.loc)) + set_holder(movable_parent) + return + var/atom/inside = movable_parent.loc //Parent's loc + if(isnull(inside)) + set_holder(null) + return + if(isturf(inside.loc)) + set_holder(inside) + return + set_holder(null) + + +///Called when the current_holder is qdeleted, to remove the light effect. +/datum/component/overlay_lighting/proc/on_holder_qdel(atom/movable/source, force) + SIGNAL_HANDLER + UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) + if(directional) + UnregisterSignal(current_holder, COMSIG_ATOM_DIR_CHANGE) + set_holder(null) + + +///Called when current_holder changes loc. +/datum/component/overlay_lighting/proc/on_holder_moved(atom/movable/source, OldLoc, Dir, Forced) + SIGNAL_HANDLER + if(!(overlay_lighting_flags & LIGHTING_ON)) + return + make_luminosity_update() + + +///Called when parent changes loc. +/datum/component/overlay_lighting/proc/on_parent_moved(atom/movable/source, OldLoc, Dir, Forced) + SIGNAL_HANDLER + var/atom/movable/movable_parent = parent + if(overlay_lighting_flags & LIGHTING_ATTACHED) + set_parent_attached_to(ismovable(movable_parent.loc) ? movable_parent.loc : null) + check_holder() + if(!(overlay_lighting_flags & LIGHTING_ON) || !current_holder) + return + make_luminosity_update() + + +///Called when the current_holder is qdeleted, to remove the light effect. +/datum/component/overlay_lighting/proc/on_parent_attached_to_qdel(atom/movable/source, force) + SIGNAL_HANDLER + UnregisterSignal(parent_attached_to, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) + if(directional) + UnregisterSignal(parent_attached_to, COMSIG_ATOM_DIR_CHANGE) + if(parent_attached_to == current_holder) + set_holder(null) + set_parent_attached_to(null) + + +///Called when parent_attached_to changes loc. +/datum/component/overlay_lighting/proc/on_parent_attached_to_moved(atom/movable/source, OldLoc, Dir, Forced) + SIGNAL_HANDLER + check_holder() + if(!(overlay_lighting_flags & LIGHTING_ON) || !current_holder) + return + make_luminosity_update() + + +///Changes the range which the light reaches. 0 means no light, 6 is the maximum value. +/datum/component/overlay_lighting/proc/set_range(atom/source, old_range) + SIGNAL_HANDLER + var/new_range = source.light_range + if(range == new_range) + return + if(range == 0) + turn_off() + range = clamp(CEILING(new_range, 0.5), 1, 6) + var/pixel_bounds = ((range - 1) * 64) + 32 + lumcount_range = CEILING(range, 1) + visible_mask.icon = light_overlays["[pixel_bounds]"] + if(pixel_bounds == 32) + visible_mask.transform = null + return + var/offset = (pixel_bounds - 32) * 0.5 + var/matrix/transform = new + transform.Translate(-offset, -offset) + visible_mask.transform = transform + if(directional) + cast_range = clamp(round(new_range * 0.5), 1, 3) + if(overlay_lighting_flags & LIGHTING_ON) + make_luminosity_update() + + +///Changes the intensity/brightness of the light by altering the visual object's alpha. +/datum/component/overlay_lighting/proc/set_power(atom/source, old_power) + SIGNAL_HANDLER + var/new_power = source.light_power + set_lum_power(new_power >= 0 ? 0.5 : -0.5) + set_alpha = min(230, (abs(new_power) * 120) + 30) + visible_mask.alpha = set_alpha + if(directional) + cone.alpha = min(200, (abs(new_power) * 90)+20) + + +///Changes the light's color, pretty straightforward. +/datum/component/overlay_lighting/proc/set_color(atom/source, old_color) + SIGNAL_HANDLER + var/new_color = source.light_color + visible_mask.color = new_color + if(directional) + cone.color = new_color + + +///Toggles the light on and off. +/datum/component/overlay_lighting/proc/on_toggle(atom/source, old_value) + SIGNAL_HANDLER + var/new_value = source.light_on + if(new_value) //Truthy value input, turn on. + turn_on() + return + turn_off() //Falsey value, turn off. + + +///Triggered right after the parent light flags change. +/datum/component/overlay_lighting/proc/on_light_flags_change(atom/source, old_flags) + SIGNAL_HANDLER + var/new_flags = source.light_flags + var/atom/movable/movable_parent = parent + if(!((new_flags ^ old_flags) & LIGHT_ATTACHED)) + return + + if(new_flags & LIGHT_ATTACHED) // Gained the [LIGHT_ATTACHED] property + overlay_lighting_flags |= LIGHTING_ATTACHED + if(ismovable(movable_parent.loc)) + set_parent_attached_to(movable_parent.loc) + else // Lost the [LIGHT_ATTACHED] property + overlay_lighting_flags &= ~LIGHTING_ATTACHED + set_parent_attached_to(null) + + +///Toggles the light on. +/datum/component/overlay_lighting/proc/turn_on() + if(overlay_lighting_flags & LIGHTING_ON) + return + if(current_holder) + if(directional) + cast_directional_light() + add_dynamic_lumi() + overlay_lighting_flags |= LIGHTING_ON + get_new_turfs() + + +///Toggles the light off. +/datum/component/overlay_lighting/proc/turn_off() + if(!(overlay_lighting_flags & LIGHTING_ON)) + return + if(current_holder) + remove_dynamic_lumi() + overlay_lighting_flags &= ~LIGHTING_ON + clean_old_turfs() + + +///Here we append the behavior associated to changing lum_power. +/datum/component/overlay_lighting/proc/set_lum_power(new_lum_power) + if(lum_power == new_lum_power) + return + . = lum_power + lum_power = new_lum_power + var/difference = . - lum_power + for(var/t in affected_turfs) + var/turf/lit_turf = t + lit_turf.dynamic_lumcount -= difference + +///Here we append the behavior associated to changing lum_power. +/datum/component/overlay_lighting/proc/cast_directional_light() + var/final_distance = cast_range + //Lower the distance by 1 if we're not looking at a cardinal direction, and we're not a short cast + if(final_distance > SHORT_CAST && !(ALL_CARDINALS & current_direction)) + final_distance -= 1 + var/turf/scanning = get_turf(current_holder) + for(var/i in 1 to final_distance) + var/turf/next_turf = get_step(scanning, current_direction) + if(isnull(next_turf) || IS_OPAQUE_TURF(next_turf)) + break + scanning = next_turf + directional_atom.forceMove(scanning) + +///Called when current_holder changes loc. +/datum/component/overlay_lighting/proc/on_holder_dir_change(atom/movable/source, olddir, newdir) + SIGNAL_HANDLER + set_direction(newdir) + +///Called when parent changes loc. +/datum/component/overlay_lighting/proc/on_parent_dir_change(atom/movable/source, olddir, newdir) + SIGNAL_HANDLER + set_direction(newdir) + +///Sets a new direction for the directional cast, then updates luminosity +/datum/component/overlay_lighting/proc/set_direction(newdir) + if(!newdir) + return + if(current_direction == newdir) + return + current_direction = newdir + cone.set_dir(newdir) + + if(newdir & NORTH) + cone.pixel_y = 16 + else if(newdir & SOUTH) + cone.pixel_y = -16 + else + if(!isnull(cone_hint_y)) + cone.pixel_y = cone_hint_y + else + cone.pixel_y = 0 + + if(newdir & EAST) + cone.pixel_x = 16 + else if(newdir & WEST) + cone.pixel_x = -16 + else + if(!isnull(cone_hint_x)) + if(newdir & NORTH) + cone.pixel_x = -1*cone_hint_x + else + cone.pixel_x = cone_hint_x + else + cone.pixel_x = 0 + + if(overlay_lighting_flags & LIGHTING_ON) + make_luminosity_update() + +/datum/component/overlay_lighting/proc/on_parent_crafted(datum/source, atom/movable/new_craft) + SIGNAL_HANDLER + + if(!istype(new_craft)) + return + + UnregisterSignal(parent, COMSIG_ATOM_USED_IN_CRAFT) + RegisterSignal(new_craft, COMSIG_ATOM_USED_IN_CRAFT, .proc/on_parent_crafted) + set_parent_attached_to(new_craft) + +/// Handles putting the source for overlay lights into the light eater queue since we aren't tracked by [/atom/var/light_sources] +/datum/component/overlay_lighting/proc/on_light_eater(datum/source, list/light_queue, datum/light_eater) + SIGNAL_HANDLER + light_queue[parent] = TRUE + return NONE + +#undef LIGHTING_ON +#undef LIGHTING_ATTACHED +#undef GET_PARENT +#undef GET_LIGHT_SOURCE +#undef SHORT_CAST diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index 5958f79d00..387adcd6c8 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -61,4 +61,92 @@ /obj/effect/temporary_effect/lightning_strike/Initialize() icon_state += "[rand(1,2)]" // To have two variants of lightning sprites. animate(src, alpha = 0, time = time_to_die - 1) - . = ..() \ No newline at end of file +<<<<<<< HEAD + . = ..() +||||||| parent of e749537a98... Merge pull request #10683 from VOREStation/Arokha/runtimes + . = ..() + +/obj/effect/dummy/lighting_obj + name = "lighting fx obj" + desc = "Tell a coder if you're seeing this." + icon_state = "nothing" + light_system = MOVABLE_LIGHT + light_range = MINIMUM_USEFUL_LIGHT_RANGE + light_color = COLOR_WHITE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + light_on = TRUE + blocks_emissive = FALSE + +/obj/effect/dummy/lighting_obj/Initialize(mapload, _range, _power, _color, _duration) + . = ..() + if(!isnull(_range)) + set_light_range(_range) + if(!isnull(_power)) + set_light_power(_power) + if(!isnull(_color)) + set_light_color(_color) + if(_duration) + QDEL_IN(src, _duration) + +/obj/effect/dummy/lighting_obj/moblight + name = "mob lighting fx" + +/obj/effect/dummy/lighting_obj/moblight/Initialize(mapload, _color, _range, _power, _duration) + . = ..() + if(!ismob(loc)) + return INITIALIZE_HINT_QDEL + +/obj/effect/dummy/lighting_obj/moblight/fire + name = "fire" + light_color = LIGHT_COLOR_FIRE + light_range = LIGHT_RANGE_FIRE + +/obj/effect/abstract/directional_lighting + mouse_opacity = MOUSE_OPACITY_TRANSPARENT +======= + . = ..() + +/obj/effect/dummy/lighting_obj + name = "lighting fx obj" + desc = "Tell a coder if you're seeing this." + icon_state = "nothing" + light_system = MOVABLE_LIGHT + light_range = MINIMUM_USEFUL_LIGHT_RANGE + light_color = COLOR_WHITE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + light_on = TRUE + blocks_emissive = FALSE + +/obj/effect/dummy/lighting_obj/Initialize(mapload, _range, _power, _color, _duration) + . = ..() + if(!isnull(_range)) + set_light_range(_range) + if(!isnull(_power)) + set_light_power(_power) + if(!isnull(_color)) + set_light_color(_color) + if(_duration) + QDEL_IN(src, _duration) + +/obj/effect/dummy/lighting_obj/moblight + name = "mob lighting fx" + +/obj/effect/dummy/lighting_obj/moblight/Initialize(mapload, _color, _range, _power, _duration) + . = ..() + if(!ismob(loc)) + return INITIALIZE_HINT_QDEL + +/obj/effect/dummy/lighting_obj/moblight/fire + name = "fire" + light_color = LIGHT_COLOR_FIRE + light_range = LIGHT_RANGE_FIRE + +/obj/effect/abstract/directional_lighting + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/effect/abstract/directional_lighting/Destroy(force) + if(!force) + stack_trace("Directional light atom deleted, but not by our component") + return QDEL_HINT_LETMELIVE + return ..() +>>>>>>> e749537a98... Merge pull request #10683 from VOREStation/Arokha/runtimes diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index b1c00bb79a..146ddebd3b 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -111,3 +111,108 @@ plane = PLANE_LIGHTING_ABOVE pixel_x = -32 pixel_y = -32 +<<<<<<< HEAD +||||||| parent of e749537a98... Merge pull request #10683 from VOREStation/Arokha/runtimes + +/obj/effect/overlay/vis + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + anchored = TRUE + vis_flags = VIS_INHERIT_DIR + ///When detected to be unused it gets set to world.time, after a while it gets removed + var/unused = 0 + ///overlays which go unused for this amount of time get cleaned up + var/cache_expiration = 2 MINUTES + +/* +/obj/effect/overlay/atmos_excited + name = "excited group" + icon = null + icon_state = null + anchored = TRUE // should only appear in vis_contents, but to be safe + appearance_flags = RESET_TRANSFORM | TILE_BOUND + invisibility = INVISIBILITY_ABSTRACT + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + + plane = ATMOS_GROUP_PLANE +*/ + +/obj/effect/overlay/light_visible + name = "" + icon = 'icons/effects/light_overlays/light_32.dmi' + icon_state = "light" + plane = PLANE_O_LIGHTING_VISUAL + appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + alpha = 0 + vis_flags = NONE + blocks_emissive = FALSE + +/obj/effect/overlay/light_cone + name = "" + icon = 'icons/effects/light_overlays/light_cone.dmi' + icon_state = "light" + plane = PLANE_O_LIGHTING_VISUAL + appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + vis_flags = NONE + alpha = 110 + blocks_emissive = FALSE + +======= + +/obj/effect/overlay/vis + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + anchored = TRUE + vis_flags = VIS_INHERIT_DIR + ///When detected to be unused it gets set to world.time, after a while it gets removed + var/unused = 0 + ///overlays which go unused for this amount of time get cleaned up + var/cache_expiration = 2 MINUTES + +/* +/obj/effect/overlay/atmos_excited + name = "excited group" + icon = null + icon_state = null + anchored = TRUE // should only appear in vis_contents, but to be safe + appearance_flags = RESET_TRANSFORM | TILE_BOUND + invisibility = INVISIBILITY_ABSTRACT + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + + plane = ATMOS_GROUP_PLANE +*/ + +/obj/effect/overlay/light_visible + name = "" + icon = 'icons/effects/light_overlays/light_32.dmi' + icon_state = "light" + plane = PLANE_O_LIGHTING_VISUAL + appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + alpha = 0 + vis_flags = NONE + blocks_emissive = FALSE + +/obj/effect/overlay/light_visible/Destroy(force) + if(!force) + stack_trace("Movable light visible mask deleted, but not by our component") + return QDEL_HINT_LETMELIVE + return ..() + +/obj/effect/overlay/light_cone + name = "" + icon = 'icons/effects/light_overlays/light_cone.dmi' + icon_state = "light" + plane = PLANE_O_LIGHTING_VISUAL + appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + vis_flags = NONE + alpha = 110 + blocks_emissive = FALSE + +/obj/effect/overlay/light_cone/Destroy(force) + if(!force) + stack_trace("Directional light cone deleted, but not by our component") + return QDEL_HINT_LETMELIVE + return ..() +>>>>>>> e749537a98... Merge pull request #10683 from VOREStation/Arokha/runtimes diff --git a/code/modules/artifice/telecube.dm b/code/modules/artifice/telecube.dm index 581b1791f8..6e7db1ebfe 100644 --- a/code/modules/artifice/telecube.dm +++ b/code/modules/artifice/telecube.dm @@ -129,7 +129,7 @@ /obj/item/weapon/telecube/proc/teleport_to_mate(var/atom/movable/A, var/areaporting = FALSE) . = FALSE - if(!A) + if(!istype(A)) return . if(A == src || A == mate) diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 22ae47b4c4..6c4ab1db13 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -148,6 +148,114 @@ obj/machinery/gateway/centerstation/process() if(dest) M.forceMove(dest.loc) M.set_dir(SOUTH) +<<<<<<< HEAD +||||||| parent of e749537a98... Merge pull request #10683 from VOREStation/Arokha/runtimes + //VOREStation Addition Start: Mcguffin time! + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(!H.client) + awaygate.entrydetect() + //VOREStation Addition End: Mcguffin time! + + //VOREStation Addition Start: Abduction! + if(istype(M, /mob/living) && dest.abductor) + var/mob/living/L = M + //Situations to get the mob out of + if(L.buckled) + L.buckled.unbuckle_mob() + if(istype(L.loc,/obj/mecha)) + var/obj/mecha/ME = L.loc + ME.go_out() + else if(istype(L.loc,/obj/machinery/sleeper)) + var/obj/machinery/sleeper/SL = L.loc + SL.go_out() + else if(istype(L.loc,/obj/machinery/recharge_station)) + var/obj/machinery/recharge_station/RS = L.loc + RS.go_out() + if(!issilicon(L)) //Don't drop borg modules... + var/list/mob_contents = list() //Things which are actually drained as a result of the above not being null. + mob_contents |= L // The recursive check below does not add the object being checked to its list. + mob_contents |= recursive_content_check(L, mob_contents, recursion_limit = 3, client_check = 0, sight_check = 0, include_mobs = 1, include_objects = 1, ignore_show_messages = 1) + for(var/obj/item/weapon/holder/I in mob_contents) + var/obj/item/weapon/holder/H = I + var/mob/living/MI = H.held_mob + MI.forceMove(get_turf(H)) + if(!issilicon(MI)) //Don't drop borg modules... + for(var/obj/item/II in MI) + if(istype(II,/obj/item/weapon/implant) || istype(II,/obj/item/device/nif)) + continue + MI.drop_from_inventory(II, dest.loc) + var/obj/effect/landmark/finaldest = pick(awayabductors) + MI.forceMove(finaldest.loc) + sleep(1) + MI.Paralyse(10) + MI << 'sound/effects/bamf.ogg' + to_chat(MI,"You're starting to come to. You feel like you've been out for a few minutes, at least...") + for(var/obj/item/I in L) + if(istype(I,/obj/item/weapon/implant) || istype(I,/obj/item/device/nif)) + continue + L.drop_from_inventory(I, dest.loc) + var/obj/effect/landmark/finaldest = pick(awayabductors) + L.forceMove(finaldest.loc) + sleep(1) + L.Paralyse(10) + L << 'sound/effects/bamf.ogg' + to_chat(L,"You're starting to come to. You feel like you've been out for a few minutes, at least...") + //VOREStation Addition End +======= + //VOREStation Addition Start: Mcguffin time! + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.client) + awaygate.entrydetect() + //VOREStation Addition End: Mcguffin time! + + //VOREStation Addition Start: Abduction! + if(istype(M, /mob/living) && dest.abductor) + var/mob/living/L = M + //Situations to get the mob out of + if(L.buckled) + L.buckled.unbuckle_mob() + if(istype(L.loc,/obj/mecha)) + var/obj/mecha/ME = L.loc + ME.go_out() + else if(istype(L.loc,/obj/machinery/sleeper)) + var/obj/machinery/sleeper/SL = L.loc + SL.go_out() + else if(istype(L.loc,/obj/machinery/recharge_station)) + var/obj/machinery/recharge_station/RS = L.loc + RS.go_out() + if(!issilicon(L)) //Don't drop borg modules... + var/list/mob_contents = list() //Things which are actually drained as a result of the above not being null. + mob_contents |= L // The recursive check below does not add the object being checked to its list. + mob_contents |= recursive_content_check(L, mob_contents, recursion_limit = 3, client_check = 0, sight_check = 0, include_mobs = 1, include_objects = 1, ignore_show_messages = 1) + for(var/obj/item/weapon/holder/I in mob_contents) + var/obj/item/weapon/holder/H = I + var/mob/living/MI = H.held_mob + MI.forceMove(get_turf(H)) + if(!issilicon(MI)) //Don't drop borg modules... + for(var/obj/item/II in MI) + if(istype(II,/obj/item/weapon/implant) || istype(II,/obj/item/device/nif)) + continue + MI.drop_from_inventory(II, dest.loc) + var/obj/effect/landmark/finaldest = pick(awayabductors) + MI.forceMove(finaldest.loc) + sleep(1) + MI.Paralyse(10) + MI << 'sound/effects/bamf.ogg' + to_chat(MI,"You're starting to come to. You feel like you've been out for a few minutes, at least...") + for(var/obj/item/I in L) + if(istype(I,/obj/item/weapon/implant) || istype(I,/obj/item/device/nif)) + continue + L.drop_from_inventory(I, dest.loc) + var/obj/effect/landmark/finaldest = pick(awayabductors) + L.forceMove(finaldest.loc) + sleep(1) + L.Paralyse(10) + L << 'sound/effects/bamf.ogg' + to_chat(L,"You're starting to come to. You feel like you've been out for a few minutes, at least...") + //VOREStation Addition End +>>>>>>> e749537a98... Merge pull request #10683 from VOREStation/Arokha/runtimes return /obj/machinery/gateway/centerstation/attackby(obj/item/device/W as obj, mob/user as mob) diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 5c2c55cf98..059905c36e 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -731,8 +731,8 @@ to_chat(H, "Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.") playsound(src, 'sound/machines/rig/rigservo.ogg', 10, FALSE) - if(piece == "helmet" && helmet) - helmet.update_light(H) + if(piece == "helmet" && helmet?.light_system == STATIC_LIGHT) + helmet.update_light() /obj/item/weapon/rig/proc/deploy(mob/M,var/sealed) diff --git a/code/modules/clothing/spacesuits/void/void.dm b/code/modules/clothing/spacesuits/void/void.dm index 81ba938ff9..a7480034ff 100644 --- a/code/modules/clothing/spacesuits/void/void.dm +++ b/code/modules/clothing/spacesuits/void/void.dm @@ -184,7 +184,9 @@ helmet.pickup(H) helmet.canremove = 0 to_chat(H, "You deploy your suit helmet, sealing you off from the world.") - helmet.update_light(H) + + if(helmet.light_system == STATIC_LIGHT) + helmet.update_light() /obj/item/clothing/suit/space/void/verb/eject_tank() diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm index 954b299b08..1733072284 100644 --- a/code/modules/food/food/snacks.dm +++ b/code/modules/food/food/snacks.dm @@ -6470,14 +6470,14 @@ nutriment_amt = 6 bitesize = 1 -/obj/item/weapon/reagent_containers/food/snacks/squid //ADDITION 04/11/2021 +/obj/item/weapon/reagent_containers/food/snacks/squid name = "\improper Calamari Crisps" icon = 'icons/obj/food_snacks.dmi' icon_state = "squid" desc = "Space squid tentacles, Carefully removed (from the squid) then dried into strips of delicious rubbery goodness!" trash = /obj/item/trash/squid filling_color = "#c0a9d7" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("fish" = 1, "salt" = 1) nutriment_amt = 2 bitesize = 1 @@ -6486,26 +6486,26 @@ . = ..() reagents.add_reagent("protein", 4) -/obj/item/weapon/reagent_containers/food/snacks/croutons //ADDITION 04/11/2021 +/obj/item/weapon/reagent_containers/food/snacks/croutons name = "\improper Suhariki" icon = 'icons/obj/food_snacks.dmi' icon_state = "croutons" desc = "Fried bread cubes. Popular in Terran territories." trash = /obj/item/trash/croutons filling_color = "#c6b17f" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("bread" = 1, "salt" = 1) nutriment_amt = 3 bitesize = 1 -/obj/item/weapon/reagent_containers/food/snacks/salo //ADDITION 04/11/2021 +/obj/item/weapon/reagent_containers/food/snacks/salo name = "\improper Salo" icon = 'icons/obj/food_snacks.dmi' icon_state = "pigfat" desc = "Pig fat. Salted. Just as good as it sounds." trash = /obj/item/trash/salo filling_color = "#e0bcbc" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("fat" = 1, "salt" = 1) nutriment_amt = 2 bitesize = 2 @@ -6514,14 +6514,14 @@ . = ..() reagents.add_reagent("protein", 8) -/obj/item/weapon/reagent_containers/food/snacks/driedfish //ADDITION 04/11/2021 +/obj/item/weapon/reagent_containers/food/snacks/driedfish name = "\improper Vobla" icon = 'icons/obj/food_snacks.dmi' icon_state = "driedfish" desc = "Dried salted beer snack fish." trash = /obj/item/trash/driedfish filling_color = "#c8a5bb" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("fish" = 1, "salt" = 1) nutriment_amt = 2 bitesize = 1 @@ -6602,7 +6602,7 @@ desc = "Contains over 9000% of your daily recommended intake of salt." trash = /obj/item/trash/tidegobs filling_color = "#2556b0" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("salt" = 4, "seagull?" = 1) nutriment_amt = 5 bitesize = 2 @@ -6614,7 +6614,7 @@ desc = "A peanut flavored snack that looks like the rings of Saturn!" trash = /obj/item/trash/saturno filling_color = "#dca319" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("salt" = 4, "peanut" = 2, "wood?" = 1) nutriment_amt = 5 bitesize = 2 @@ -6626,7 +6626,7 @@ desc = "By Joove! It's some kind of gel." trash = /obj/item/trash/jupiter filling_color = "#dc1919" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("sweetness" = 4, "vanilla" = 1) nutriment_amt = 5 bitesize = 2 @@ -6638,7 +6638,7 @@ desc = "Baseless tasteless nutrithick rods to get you through the day. Now even less rash inducing!" trash = /obj/item/trash/pluto filling_color = "#ffffff" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("chalk" = 4, "sadness" = 1) nutriment_amt = 5 bitesize = 2 @@ -6650,7 +6650,7 @@ desc = "A steaming self-heated bowl of sweet eggs and taters!" trash = /obj/item/trash/mars filling_color = "#d2c63f" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("eggs" = 4, "potato" = 4, "mustard" = 2) nutriment_amt = 8 bitesize = 2 @@ -6662,7 +6662,7 @@ desc = "Hot takes on hot cakes, a timeless classic now finally fit for human consumption!" trash = /obj/item/trash/venus filling_color = "#d2c63f" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("heat" = 4, "burning!" = 1) nutriment_amt = 5 bitesize = 2 @@ -6678,7 +6678,7 @@ desc = "A Sol favorite, Sun Snax! Sun dried corn chips coated in a super spicy seasoning!" trash = /obj/item/trash/sun_snax filling_color = "#d2c63f" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("heat" = 3, "burning!" = 2) nutriment_amt = 3 bitesize = 1 @@ -6694,7 +6694,7 @@ desc = "Pop rocks themed on the outermost reaches of the Sol system, new formula guarantees fewer shrapnel induced oral injuries." trash = /obj/item/trash/oort filling_color = "#3f7dd2" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("fizz" = 4, "sweetness" = 1) nutriment_amt = 5 bitesize = 2 @@ -6710,7 +6710,7 @@ trash = /obj/item/trash/pretzel desc = "A tasty bread like snack that is seasoned with what tastes like salt... but you're not so sure it's actually salt." filling_color = "#916E36" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("salt" = 2, "pretzel" = 3) nutriment_amt = 3 bitesize = 1 @@ -6723,7 +6723,7 @@ desc = "Fermented space shark, like chewing a urine soaked mattress." description_fluff = "A form of fermented shark that originated on Earth as far back as the 17th century. Modern Hakarl is made from vat-made fermented shark and is distributed across the galaxy as a delicacy. However, few are able to stand the smell or taste of the meat." filling_color = "#916E36" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("fish" = 2, "salt" = 2, "ammonia" = 1) nutriment_amt = 4 bitesize = 1 @@ -6835,7 +6835,7 @@ /obj/item/weapon/reagent_containers/food/snacks/old name = "master old-food" desc = "they're all inedible and potentially dangerous items" - center_of_mass = "x=15;y=12" + center_of_mass = list("x"=15,"y"=12) nutriment_desc = list("rot" = 5, "mold" = 5) nutriment_amt = 10 bitesize = 3 @@ -6920,7 +6920,7 @@ desc = "A can of premium preserved vat-grown holstein beef. Now 99.9% bone free!" trash = /obj/item/trash/beef filling_color = "#663300" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("beef" = 1) bitesize = 2 @@ -6935,7 +6935,7 @@ desc = "Luna Colony beans. Carefully synthethized from soy." trash = /obj/item/trash/beans filling_color = "#ff6633" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("beans" = 1, "tomato sauce" = 1) nutriment_amt = 10 bitesize = 2 @@ -6950,7 +6950,7 @@ // desc = "Plain old unseasoned tomato soup. This can has no use-by date." // trash = "/obj/item/trash/tomato" // filling_color = "#ae0000" -// center_of_mass = "x=15;y=9" +// center_of_mass = list("x"=15, "y"=9) // nutriment_desc = list("tomato" = 1) // bitesize = 3 // eat_sound = 'sound/items/drink.ogg' @@ -6969,7 +6969,7 @@ desc = "Wup-Az! Brand canned spinach. Notably has less iron in it than a watermelon." trash = /obj/item/trash/spinach filling_color = "#003300" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("soggy" = 1, "vegetable" = 1) bitesize = 5 @@ -6988,7 +6988,7 @@ desc = "Terran caviar, or space carp eggs. Carefully faked using alginate, artificial flavoring and salt. Skrell approved!" trash = /obj/item/trash/fishegg filling_color = "#000000" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("fish" = 1, "salt" = 1) nutriment_amt = 6 bitesize = 1 @@ -7003,7 +7003,7 @@ desc = "Terran caviar, or space carp eggs. Banned by the Vir Food Health Administration for exceeding the legally set amount of carpotoxins in food stuffs." trash = /obj/item/trash/carpegg filling_color = "#330066" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("fish" = 1, "salt" = 1, "a numbing sensation" = 1) nutriment_amt = 6 bitesize = 1 @@ -7019,7 +7019,7 @@ desc = "A re-branding of a classic Terran snack! Contains mostly edible ingredients." trash = /obj/item/trash/maps filling_color = "#330066" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("meat" = 1, "salt" = 1) nutriment_amt = 8 bitesize = 2 @@ -7035,7 +7035,7 @@ desc = "A classic snack favored by Sol astronauts. Made from dried apple-hybidized berries grown on the lunar colonies." trash = /obj/item/trash/appleberry filling_color = "#FFFFFF" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("apple" = 1, "sweetness" = 1) nutriment_amt = 8 bitesize = 2 @@ -7085,7 +7085,7 @@ desc = "Now with 20% less lawsuit enabling rhegolith!" //trash = /obj/item/trash/lunacakewrap //need to add code that drops trash but keeps -open state filling_color = "#ffffff" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("sweetness" = 4, "vanilla" = 1) bitesize = 2 @@ -7099,7 +7099,7 @@ desc = "Explore the dark side! May contain trace amounts of reconstituted cocoa." //trash = /obj/item/trash/mooncakewrap //need to add code that drops trash but keeps -open state filling_color = "#ffffff" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("sweetness" = 4, "chocolate" = 1) bitesize = 2 @@ -7113,7 +7113,7 @@ desc = "Konnichiwa! Many go lucky rice cakes in future!" //trash = /obj/item/trash/mochicakewrap //need to add code that drops trash but keeps -open state filling_color = "#ffffff" - center_of_mass = "x=15;y=9" + center_of_mass = list("x"=15, "y"=9) nutriment_desc = list("sweetness" = 4, "rice" = 1) bitesize = 2