diff --git a/code/__DEFINES/uplink.dm b/code/__DEFINES/uplink.dm index cdfdf4680f7929..929b558dfec475 100644 --- a/code/__DEFINES/uplink.dm +++ b/code/__DEFINES/uplink.dm @@ -36,7 +36,7 @@ /// Typepath used for uplink items which don't actually produce an item (essentially just a placeholder) /// Future todo: Make this not necessary / make uplink items support item-less items natively -#define ABSTRACT_UPLINK_ITEM /obj/effect/gibspawner/generic +#define ABSTRACT_UPLINK_ITEM /obj/item/loot_table_maker /// Lower threshold for which an uplink items's TC cost is considered "low" for spy bounties picking rewards #define SPY_LOWER_COST_THRESHOLD 5 diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index dc425083ad8960..3bd370120b3a42 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -317,14 +317,14 @@ GLOBAL_LIST_EMPTY(radial_menus) current_page = WRAP(current_page + 1,1,pages+1) update_screen_objects() -/datum/radial_menu/proc/show_to(mob/M) +/datum/radial_menu/proc/show_to(mob/M, offset_x = 0, offset_y = 0) if(current_user) hide() if(!M.client || !anchor) return current_user = M.client //Blank - menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing", layer = RADIAL_BACKGROUND_LAYER) + menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing", layer = RADIAL_BACKGROUND_LAYER, pixel_x = offset_x, pixel_y = offset_y) SET_PLANE_EXPLICIT(menu_holder, ABOVE_HUD_PLANE, M) menu_holder.appearance_flags |= KEEP_APART|RESET_ALPHA|RESET_COLOR|RESET_TRANSFORM menu_holder.vis_contents += elements + close_button @@ -356,7 +356,7 @@ GLOBAL_LIST_EMPTY(radial_menus) Choices should be a list where list keys are movables or text used for element names and return value and list values are movables/icons/images used for element icons */ -/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE, no_repeat_close = FALSE, radial_slice_icon = "radial_slice", autopick_single_option = TRUE, entry_animation = TRUE, click_on_hover = FALSE) +/proc/show_radial_menu(mob/user, atom/anchor, list/choices, uniqueid, radius, datum/callback/custom_check, require_near = FALSE, tooltips = FALSE, no_repeat_close = FALSE, radial_slice_icon = "radial_slice", autopick_single_option = TRUE, entry_animation = TRUE, click_on_hover = FALSE, user_space = FALSE) if(!user || !anchor || !length(choices)) return @@ -379,11 +379,18 @@ GLOBAL_LIST_EMPTY(radial_menus) menu.radius = radius if(istype(custom_check)) menu.custom_check_callback = custom_check - menu.anchor = anchor + menu.anchor = user_space ? user : anchor menu.radial_slice_icon = radial_slice_icon menu.check_screen_border(user) //Do what's needed to make it look good near borders or on hud menu.set_choices(choices, tooltips, click_on_hover) - menu.show_to(user) + var/offset_x = 0 + var/offset_y = 0 + if (user_space) + var/turf/user_turf = get_turf(user) + var/turf/anchor_turf = get_turf(anchor) + offset_x = (anchor_turf.x - user_turf.x) * world.icon_size + anchor.pixel_x - user.pixel_x + offset_y = (anchor_turf.y - user_turf.y) * world.icon_size + anchor.pixel_y - user.pixel_y + menu.show_to(user, offset_x, offset_y) menu.wait(user, anchor, require_near) var/answer = menu.selected_choice qdel(menu) diff --git a/code/datums/components/callouts.dm b/code/datums/components/callouts.dm index 24e7f081fbe78a..98d489cc915a97 100644 --- a/code/datums/components/callouts.dm +++ b/code/datums/components/callouts.dm @@ -111,7 +111,7 @@ for(var/datum/callout_option/callout_option as anything in callout_options) callout_items[callout_option] = image(icon = 'icons/hud/radial.dmi', icon_state = callout_option::icon_state) - var/datum/callout_option/selection = show_radial_menu(user, get_turf(clicked_atom), callout_items, entry_animation = FALSE, click_on_hover = TRUE) + var/datum/callout_option/selection = show_radial_menu(user, get_turf(clicked_atom), callout_items, entry_animation = FALSE, click_on_hover = TRUE, user_space = TRUE) if (!selection) return diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index a5ff46964bf6fa..d831ba2f0d964a 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -227,9 +227,12 @@ for(var/datum/uplink_item/item as anything in uplink_handler.extra_purchasable) if(item.stock_key in stock_list) extra_purchasable_stock[REF(item)] = stock_list[item.stock_key] + var/atom/actual_item = item.item extra_purchasable += list(list( "id" = item.type, "name" = item.name, + "icon" = actual_item.icon, + "icon_state" = actual_item.icon_state, "cost" = item.cost, "desc" = item.desc, "category" = item.category ? initial(item.category.name) : null, @@ -288,6 +291,11 @@ return item = SStraitor.uplink_items_by_type[item_path] uplink_handler.purchase_item(ui.user, item, parent) + if("buy_raw_tc") + if (uplink_handler.telecrystals <= 0) + return + var/desired_amount = tgui_input_number(ui.user, "How many raw telecrystals to buy?", "Buy Raw TC", default = uplink_handler.telecrystals, max_value = uplink_handler.telecrystals) + uplink_handler.purchase_raw_tc(ui.user, desired_amount, parent) if("lock") if(!lockable) return TRUE diff --git a/code/game/objects/effects/particles/fire.dm b/code/game/objects/effects/particles/fire.dm index 9d90d0d29c29a4..9904685807364b 100644 --- a/code/game/objects/effects/particles/fire.dm +++ b/code/game/objects/effects/particles/fire.dm @@ -33,3 +33,21 @@ drift = generator(GEN_VECTOR, list(-0.1,0), list(0.1,0.025), UNIFORM_RAND) spin = generator(GEN_NUM, list(-15,15), NORMAL_RAND) scale = generator(GEN_VECTOR, list(0.5,0.5), list(2,2), NORMAL_RAND) + +/particles/embers/spark + count = 3 + spawning = 2 + gradient = list("#FBAF4D", "#FCE6B6", "#FFFFFF") + lifespan = 1.5 SECONDS + fade = 1 SECONDS + fadein = 0.1 SECONDS + grow = -0.1 + velocity = generator(GEN_CIRCLE, 3, 3, SQUARE_RAND) + position = generator(GEN_SPHERE, 0, 0, LINEAR_RAND) + scale = generator(GEN_VECTOR, list(0.5, 0.5), list(1,1), NORMAL_RAND) + drift = list(0) + +/particles/embers/spark/severe + count = 10 + spawning = 5 + gradient = list("#FCE6B6", "#FFFFFF") diff --git a/code/game/objects/effects/particles/smoke.dm b/code/game/objects/effects/particles/smoke.dm index 27249c65a683e2..776c90534a957b 100644 --- a/code/game/objects/effects/particles/smoke.dm +++ b/code/game/objects/effects/particles/smoke.dm @@ -84,3 +84,16 @@ grow = 0.05 spin = 2 color = "#fcffff77" + +/particles/smoke/cyborg + count = 5 + spawning = 1 + lifespan = 1 SECONDS + fade = 1.8 SECONDS + position = list(0, 0, 0) + scale = list(0.5, 0.5) + grow = 0.1 + +/particles/smoke/cyborg/heavy_damage + lifespan = 0.8 SECONDS + fade = 0.8 SECONDS diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index b2b0109c04c882..fb40a70cbeea0e 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -145,22 +145,30 @@ if(user.combat_mode) return NONE + return try_heal_loop(interacting_with, user) + +/obj/item/weldingtool/proc/try_heal_loop(atom/interacting_with, mob/living/user, repeating = FALSE) var/mob/living/carbon/human/attacked_humanoid = interacting_with var/obj/item/bodypart/affecting = attacked_humanoid.get_bodypart(check_zone(user.zone_selected)) if(isnull(affecting) || !IS_ROBOTIC_LIMB(affecting)) return NONE - var/use_delay = 0 + if (!affecting.get_damage()) + return + user.visible_message(span_notice("[user] starts to fix some of the dents on [attacked_humanoid == user ? user.p_their() : "[attacked_humanoid]'s"] [affecting.name]."), + span_notice("You start fixing some of the dents on [attacked_humanoid == user ? "your" : "[attacked_humanoid]'s"] [affecting.name].")) + var/use_delay = repeating ? 1 SECONDS : 0 if(user == attacked_humanoid) - user.visible_message(span_notice("[user] starts to fix some of the dents on [attacked_humanoid]'s [affecting.name]."), - span_notice("You start fixing some of the dents on [attacked_humanoid == user ? "your" : "[attacked_humanoid]'s"] [affecting.name].")) use_delay = 5 SECONDS if(!use_tool(attacked_humanoid, user, use_delay, volume=50, amount=1)) return ITEM_INTERACT_BLOCKING - attacked_humanoid.item_heal(user, brute_heal = 15, burn_heal = 0, heal_message_brute = "dents", heal_message_burn = "burnt wires", required_bodytype = BODYTYPE_ROBOTIC) + if (!attacked_humanoid.item_heal(user, brute_heal = 15, burn_heal = 0, heal_message_brute = "dents", heal_message_burn = "burnt wires", required_bodytype = BODYTYPE_ROBOTIC)) + return ITEM_INTERACT_BLOCKING + + INVOKE_ASYNC(src, PROC_REF(try_heal_loop), interacting_with, user, TRUE) return ITEM_INTERACT_SUCCESS /obj/item/weldingtool/afterattack(atom/target, mob/user, click_parameters) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 895660fafa44c1..8dc8d82ff5f7de 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -356,6 +356,7 @@ if((shove_flags & SHOVE_KNOCKDOWN_BLOCKED) || !(shove_flags & SHOVE_BLOCKED)) return target.Knockdown(SHOVE_KNOCKDOWN_TABLE) + target.apply_status_effect(/datum/status_effect/next_shove_stuns) target.visible_message(span_danger("[shover.name] shoves [target.name] onto \the [src]!"), span_userdanger("You're shoved onto \the [src] by [shover.name]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, shover) to_chat(shover, span_danger("You shove [target.name] onto \the [src]!")) diff --git a/code/modules/admin/verbs/lua/lua_editor.dm b/code/modules/admin/verbs/lua/lua_editor.dm index c0b37fd87c1ec9..a28ae8b40f19bf 100644 --- a/code/modules/admin/verbs/lua/lua_editor.dm +++ b/code/modules/admin/verbs/lua/lua_editor.dm @@ -75,6 +75,7 @@ if(last_error) data["lastError"] = last_error last_error = null + data["supressRuntimes"] = current_state.supress_runtimes data["states"] = list() for(var/datum/lua_state/state as anything in SSlua.states) data["states"] += state.display_name @@ -228,7 +229,7 @@ if(result["status"] == "error") last_error = result["message"] arguments.Cut() - return TRUE + return if("resumeTask") var/task_index = params["index"] SSlua.queue_resume(current_state, task_index, arguments) @@ -261,6 +262,9 @@ if("toggleShowGlobalTable") show_global_table = !show_global_table return TRUE + if("toggleSupressRuntimes") + current_state.supress_runtimes = !current_state.supress_runtimes + return TRUE if("nextPage") page = min(page+1, CEILING(current_state.log.len/50, 1)-1) return TRUE diff --git a/code/modules/admin/verbs/lua/lua_state.dm b/code/modules/admin/verbs/lua/lua_state.dm index b3ede122384448..37a60f1fdb5e14 100644 --- a/code/modules/admin/verbs/lua/lua_state.dm +++ b/code/modules/admin/verbs/lua/lua_state.dm @@ -24,6 +24,9 @@ GLOBAL_PROTECT(lua_state_stack) /// Whether the timer.lua script has been included into this lua context state. var/timer_enabled = FALSE + /// Whether to supress logging BYOND runtimes for this state. + var/supress_runtimes = FALSE + /// Callbacks that need to be ran on next tick var/list/functions_to_execute = list() diff --git a/code/modules/antagonists/traitor/uplink_handler.dm b/code/modules/antagonists/traitor/uplink_handler.dm index f78ddb0247892a..2d27f3c4a0eff4 100644 --- a/code/modules/antagonists/traitor/uplink_handler.dm +++ b/code/modules/antagonists/traitor/uplink_handler.dm @@ -126,6 +126,21 @@ on_update() return TRUE +/datum/uplink_handler/proc/purchase_raw_tc(mob/user, amount, atom/movable/source) + if(shop_locked) + return FALSE + if(telecrystals < amount) + return FALSE + + telecrystals -= amount + var/tcs = new /obj/item/stack/telecrystal(get_turf(user), amount) + user.put_in_hands(tcs) + + log_uplink("[key_name(user)] purchased [amount] raw telecrystals from [source]'s uplink") + on_update() + return TRUE + + /// Generates objectives for this uplink handler /datum/uplink_handler/proc/generate_objectives() var/potential_objectives_left = maximum_potential_objectives - (length(potential_objectives) + length(active_objectives)) diff --git a/code/modules/asset_cache/assets/uplink.dm b/code/modules/asset_cache/assets/uplink.dm index e85ee1b35b5c13..35a907a234dfa3 100644 --- a/code/modules/asset_cache/assets/uplink.dm +++ b/code/modules/asset_cache/assets/uplink.dm @@ -18,10 +18,13 @@ for(var/datum/uplink_item/item_path as anything in subtypesof(/datum/uplink_item)) var/datum/uplink_item/item = new item_path() + var/atom/actual_item = item.item if(item.item) { items += list(list( "id" = item_path, "name" = item.name, + "icon" = actual_item.icon, + "icon_state" = actual_item.icon_state, "cost" = item.cost, "desc" = item.desc, "category" = item.category ? initial(item.category.name) : null, diff --git a/code/modules/bitrunning/components/avatar_connection.dm b/code/modules/bitrunning/components/avatar_connection.dm index 51263c339319eb..abf3a7809fcda2 100644 --- a/code/modules/bitrunning/components/avatar_connection.dm +++ b/code/modules/bitrunning/components/avatar_connection.dm @@ -20,7 +20,7 @@ help_text, ) - if(!isliving(parent) || !isliving(old_body) || !server.is_operational || !pod.is_operational) + if(!isliving(parent) || !isliving(old_body) || !old_mind || !server.is_operational || !pod.is_operational) return COMPONENT_INCOMPATIBLE var/mob/living/avatar = parent @@ -66,6 +66,9 @@ if(alias && avatar.real_name != alias) avatar.fully_replace_character_name(avatar.real_name, alias) + for(var/skill_type in old_mind.known_skills) + avatar.mind.set_experience(skill_type, old_mind.get_skill_exp(skill_type), silent = TRUE) + avatar.playsound_local(avatar, 'sound/magic/blink.ogg', 25, TRUE) avatar.set_static_vision(2 SECONDS) avatar.set_temp_blindness(1 SECONDS) // I'm in @@ -281,6 +284,10 @@ if(isnull(old_mind) || isnull(old_body)) return + for(var/skill_type in avatar.mind.known_skills) + old_mind.set_experience(skill_type, avatar.mind.get_skill_exp(skill_type), silent = TRUE) + avatar.mind.set_experience(skill_type, 0, silent = TRUE) + ghost.mind = old_mind if(old_body.stat != DEAD) old_mind.transfer_to(old_body, force_key_move = TRUE) diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm index 86ee482a9109d9..69b9342007c41d 100644 --- a/code/modules/cargo/supplypod.dm +++ b/code/modules/cargo/supplypod.dm @@ -421,18 +421,22 @@ insert(turf_underneath, holder) /obj/structure/closet/supplypod/insert(atom/to_insert, atom/movable/holder) - if(insertion_allowed(to_insert)) - if(isturf(to_insert)) - var/turf/turf_to_insert = to_insert - turfs_in_cargo += turf_to_insert.type - turf_to_insert.ScrapeAway() - else - var/atom/movable/movable_to_insert = to_insert - movable_to_insert.forceMove(holder) - return TRUE - else + if(!insertion_allowed(to_insert)) return FALSE + if(isturf(to_insert)) + var/turf/turf_to_insert = to_insert + turfs_in_cargo += turf_to_insert.type + turf_to_insert.ScrapeAway() + return TRUE + + var/atom/movable/movable_to_insert = to_insert + if (ismob(movable_to_insert)) + var/mob/mob_to_insert = movable_to_insert + if (!isnull(mob_to_insert.buckled)) + mob_to_insert.buckled.unbuckle_mob(mob_to_insert, force = TRUE) + movable_to_insert.forceMove(holder) + /obj/structure/closet/supplypod/insertion_allowed(atom/to_insert) if(to_insert.invisibility == INVISIBILITY_ABSTRACT) return FALSE diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index feaa93424f9a88..4a0419f98f55f4 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -57,6 +57,11 @@ GLOBAL_LIST_INIT(specific_fish_icons, zebra_typecacheof(list( var/explosive_malus = FALSE /// If explosive_malus is true, this will be used to keep track of the turfs where an explosion happened for when we'll spawn the loot. var/list/exploded_turfs + /// Mindless mobs that can fish will never pull up items on this list + var/static/list/profound_fisher_blacklist = typecacheof(list( + /mob/living/basic/mining/lobstrosity, + /obj/structure/closet/crate/necropolis/tendril, + )) /datum/fish_source/New() if(!PERFORM_ALL_TESTS(focus_only/fish_sources_tables)) @@ -276,6 +281,9 @@ GLOBAL_LIST(fishing_property_cache) var/list/fish_list_properties = collect_fish_properties() + + if(HAS_TRAIT(fisherman, TRAIT_PROFOUND_FISHER) && !fisherman.client) + final_table -= profound_fisher_blacklist for(var/result in final_table) final_table[result] *= rod.hook?.get_hook_bonus_multiplicative(result) final_table[result] += rod.hook?.get_hook_bonus_additive(result)//Decide on order here so it can be multiplicative diff --git a/code/modules/mob/living/silicon/robot/death.dm b/code/modules/mob/living/silicon/robot/death.dm index 3a8cec66efd6fb..5c4384302b8d69 100644 --- a/code/modules/mob/living/silicon/robot/death.dm +++ b/code/modules/mob/living/silicon/robot/death.dm @@ -21,18 +21,30 @@ else logevent("FATAL -- SYSTEM HALT") modularInterface.shutdown_computer() + eye_flash_timer = addtimer(CALLBACK(src, PROC_REF(flash_headlamp)), 2 SECONDS, TIMER_STOPPABLE | TIMER_LOOP) . = ..() locked = FALSE //unlock cover if(!QDELETED(builtInCamera) && builtInCamera.camera_enabled) builtInCamera.toggle_cam(src,0) - toggle_headlamp(TRUE) //So borg lights are disabled when killed. + toggle_headlamp(TRUE) //So borg lights are disabled when killed. drop_all_held_items() // particularly to ensure sight modes are cleared - update_icons() - unbuckle_all_mobs(TRUE) - SSblackbox.ReportDeath(src) + +/mob/living/silicon/robot/proc/flash_headlamp() + if(eye_lights) + eye_lights = null + regenerate_icons() + return + + eye_lights = new() + eye_lights.icon_state = "[model.special_light_key ? "[model.special_light_key]":"[model.cyborg_base_icon]"]_e_r" + eye_lights.color = COLOR_WHITE + SET_PLANE_EXPLICIT(eye_lights, ABOVE_GAME_PLANE, src) + eye_lights.icon = icon + regenerate_icons() + add_overlay(eye_lights) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 3fcf652cc6abb0..4871370d16c3d0 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -583,6 +583,7 @@ /mob/living/silicon/robot/updatehealth() ..() + update_damage_particles() if(!model.breakable_modules) return @@ -680,6 +681,9 @@ builtInCamera.toggle_cam(src, 0) if(full_heal_flags & HEAL_ADMIN) locked = TRUE + if(eye_flash_timer) + deltimer(eye_flash_timer) + eye_flash_timer = null src.set_stat(CONSCIOUS) notify_ai(AI_NOTIFICATION_NEW_BORG) toggle_headlamp(FALSE, TRUE) //This will reenable borg headlamps if doomsday is currently going on still. diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 549762fd7a943d..16da8d89783af7 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -186,6 +186,52 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real return ..() +#define LOW_DAMAGE_UPPER_BOUND 1/3 +#define MODERATE_DAMAGE_UPPER_BOUND 2/3 + +/mob/living/silicon/robot/proc/update_damage_particles() + var/brute_percent = bruteloss / maxHealth + var/burn_percent = fireloss / maxHealth + + if (brute_percent > MODERATE_DAMAGE_UPPER_BOUND) + if(!smoke_particles) + smoke_particles = new(src, /particles/smoke/cyborg/heavy_damage, PARTICLE_ATTACH_MOB) + else if(!istype(smoke_particles.particles, /particles/smoke/cyborg/heavy_damage)) //TODO: needs to be darker + QDEL_NULL(smoke_particles) + smoke_particles = new(src, /particles/smoke/cyborg/heavy_damage, PARTICLE_ATTACH_MOB) + + else if (brute_percent > LOW_DAMAGE_UPPER_BOUND) + if(!smoke_particles) + smoke_particles = new(src, /particles/smoke/cyborg, PARTICLE_ATTACH_MOB) + else if(!istype(smoke_particles.particles, /particles/smoke/cyborg)) + QDEL_NULL(smoke_particles) + smoke_particles = new(src, /particles/smoke/cyborg, PARTICLE_ATTACH_MOB) + + else + if(smoke_particles) + QDEL_NULL(smoke_particles) + + if (burn_percent > MODERATE_DAMAGE_UPPER_BOUND) + if(!spark_particles) + spark_particles = new(src, /particles/embers/spark/severe, PARTICLE_ATTACH_MOB) + else if(!istype(spark_particles.particles, /particles/embers/spark/severe)) //TODO: needs to be more dramatic + QDEL_NULL(spark_particles) + spark_particles = new(src, /particles/embers/spark/severe, PARTICLE_ATTACH_MOB) + + else if (burn_percent > LOW_DAMAGE_UPPER_BOUND) + if(!spark_particles) + spark_particles = new(src, /particles/embers/spark, PARTICLE_ATTACH_MOB) + else if(!istype(spark_particles.particles, /particles/embers/spark)) + QDEL_NULL(spark_particles) + spark_particles = new(src, /particles/embers/spark, PARTICLE_ATTACH_MOB) + + else + if(spark_particles) + QDEL_NULL(spark_particles) + +#undef LOW_DAMAGE_UPPER_BOUND +#undef MODERATE_DAMAGE_UPPER_BOUND + /mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/adult/user, list/modifiers) if (LAZYACCESS(modifiers, RIGHT_CLICK)) if(body_position == STANDING_UP) @@ -401,7 +447,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real if(stat != DEAD) adjustBruteLoss(30) else - investigate_log("has been gibbed a blob.", INVESTIGATE_DEATHS) + investigate_log("has been gibbed by a blob.", INVESTIGATE_DEATHS) gib(DROP_ALL_REMAINS) return TRUE diff --git a/code/modules/mob/living/silicon/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm index 33026d70921fbe..e6af597bc60b70 100644 --- a/code/modules/mob/living/silicon/robot/robot_defines.dm +++ b/code/modules/mob/living/silicon/robot/robot_defines.dm @@ -57,6 +57,8 @@ // Overlay for borg eye lights var/mutable_appearance/eye_lights + ///Holds a reference to the timer taking care of blinking lights on dead cyborgs + var/eye_flash_timer = null // Overlay for borg hat var/mutable_appearance/hat_overlay @@ -115,6 +117,10 @@ var/low_power_mode = FALSE ///So they can initialize sparks whenever/N var/datum/effect_system/spark_spread/spark_system + ///Smoke particle holder for brute damage + var/obj/effect/abstract/particle_holder/smoke_particles = null + ///Spark particle holder for burn damage + var/obj/effect/abstract/particle_holder/spark_particles = null ///Jetpack-like effect. var/ionpulse = FALSE diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index 78ff7e9952bd10..cf91aaf482c224 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -537,7 +537,7 @@ radial_anchor = get_turf(user.loc) //they're phased out via some module, anchor the radial on the turf so it may still display if (!isnull(anchor_override)) radial_anchor = anchor_override - var/pick = show_radial_menu(user, radial_anchor, items, custom_check = FALSE, require_near = isnull(anchor_override), tooltips = TRUE) + var/pick = show_radial_menu(user, radial_anchor, items, custom_check = FALSE, require_near = isnull(anchor_override), tooltips = TRUE, user_space = !isnull(anchor_override)) if(!pick) return var/module_reference = display_names[pick] diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index a8e20cde8c7a0b..65b4f017229598 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -565,22 +565,42 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri // General procedures /////////////////////////////////// //you can use wires to heal robotics -/obj/item/stack/cable_coil/attack(mob/living/carbon/human/H, mob/user) - if(!istype(H)) - return ..() - var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - if(affecting && IS_ROBOTIC_LIMB(affecting)) - if(user == H) - user.visible_message(span_notice("[user] starts to fix some of the wires in [H]'s [affecting.name]."), span_notice("You start fixing some of the wires in [H == user ? "your" : "[H]'s"] [affecting.name].")) - if(!do_after(user, 5 SECONDS, H)) - return - if(H.item_heal(user, 0, 15, "dents", "burnt wires", BODYTYPE_ROBOTIC)) - use(1) +/obj/item/stack/cable_coil/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + if(!ishuman(interacting_with)) + return NONE + + if(user.combat_mode) + return NONE + + return try_heal_loop(interacting_with, user) + +/obj/item/stack/cable_coil/proc/try_heal_loop(atom/interacting_with, mob/living/user, repeating = FALSE) + var/mob/living/carbon/human/attacked_humanoid = interacting_with + var/obj/item/bodypart/affecting = attacked_humanoid.get_bodypart(check_zone(user.zone_selected)) + if(isnull(affecting) || !IS_ROBOTIC_LIMB(affecting)) + return NONE + + if (!affecting.get_damage()) return - else - return ..() + user.visible_message(span_notice("[user] starts to fix some of the wires in [attacked_humanoid == user ? user.p_their() : "[attacked_humanoid]'s"] [affecting.name]."), + span_notice("You start fixing some of the wires in [attacked_humanoid == user ? "your" : "[attacked_humanoid]'s"] [affecting.name].")) + + var/use_delay = repeating ? 1 SECONDS : 0 + if(user == attacked_humanoid) + use_delay = 5 SECONDS + + if(!do_after(user, use_delay, attacked_humanoid)) + return ITEM_INTERACT_BLOCKING + + if (!attacked_humanoid.item_heal(user, brute_heal = 0, burn_heal = 15, heal_message_brute = "dents", heal_message_burn = "burnt wires", required_bodytype = BODYTYPE_ROBOTIC)) + return ITEM_INTERACT_BLOCKING + + if (use(1) && amount > 0) + INVOKE_ASYNC(src, PROC_REF(try_heal_loop), interacting_with, user, TRUE) + + return ITEM_INTERACT_SUCCESS /////////////////////////////////////////////// // Cable laying procedures diff --git a/code/modules/uplink/uplink_items/bundle.dm b/code/modules/uplink/uplink_items/bundle.dm index dae6166d49cebd..b6cdc2fd3d6578 100644 --- a/code/modules/uplink/uplink_items/bundle.dm +++ b/code/modules/uplink/uplink_items/bundle.dm @@ -40,18 +40,7 @@ // Don't add telecrystals to the purchase_log since // it's just used to buy more items (including itself!) purchase_log_vis = FALSE - -/datum/uplink_item/bundles_tc/telecrystal/five - name = "5 Raw Telecrystals" - desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/five - cost = 5 - -/datum/uplink_item/bundles_tc/telecrystal/twenty - name = "20 Raw Telecrystals" - desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/twenty - cost = 20 + purchasable_from = NONE /datum/uplink_item/bundles_tc/bundle_a name = "Syndi-kit Tactical" diff --git a/html/changelogs/AutoChangeLog-pr-85443.yml b/html/changelogs/AutoChangeLog-pr-85443.yml deleted file mode 100644 index e3459099c07d13..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-85443.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Bamboo staves can now be wielded" - - bugfix: "Bostaff no longer disappears forever when wielded" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-85445.yml b/html/changelogs/AutoChangeLog-pr-85445.yml deleted file mode 100644 index 918cfdb676eb61..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-85445.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "FlufflesTheDog" -delete-after: True -changes: - - bugfix: "Existing gas flow meters have been recalled and replaced due to a faulty screen connection, and once again convey pressure and temperature" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-85448.yml b/html/changelogs/AutoChangeLog-pr-85448.yml deleted file mode 100644 index 270d19314e31ae..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-85448.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "carlarctg" -delete-after: True -changes: - - rscadd: "Adds a bronze dimensional theme" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-85454.yml b/html/changelogs/AutoChangeLog-pr-85454.yml deleted file mode 100644 index f6b0ce36ed3774..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-85454.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Majkl-J" -delete-after: True -changes: - - bugfix: "Flashdarks now broduce darkness upon toggling" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-85457.yml b/html/changelogs/AutoChangeLog-pr-85457.yml deleted file mode 100644 index 9fdd6e881a5323..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-85457.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SmArtKar" -delete-after: True -changes: - - bugfix: "Rice hat no longer disappears upon being toggled and can be raised back up. Toggling sprites is now done by alt-clicking" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-85462.yml b/html/changelogs/AutoChangeLog-pr-85462.yml deleted file mode 100644 index 2f30fe9f45dba6..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-85462.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Jacquerel" -delete-after: True -changes: - - admin: "Adds some missing traits to the mob trait list in VV" \ No newline at end of file diff --git a/html/changelogs/archive/2024-08.yml b/html/changelogs/archive/2024-08.yml index 7b10ef0da9589b..27ac50a47b3a12 100644 --- a/html/changelogs/archive/2024-08.yml +++ b/html/changelogs/archive/2024-08.yml @@ -99,3 +99,46 @@ - rscadd: 'durathread robes can now store botany gear :cl:' +2024-08-02: + FlufflesTheDog: + - bugfix: Existing gas flow meters have been recalled and replaced due to a faulty + screen connection, and once again convey pressure and temperature + Ghommie: + - qol: Skills are passed down to bitrunning avatars and then back to the original + body. + - bugfix: Stop clientless lobstrosities from fishing other lobstrosities, which + in turn can fish other lobstrosities and so on. + - balance: Stop clientless lobstrosities from fishing the lavaland fishing spot + chest. + Jacquerel: + - admin: Adds some missing traits to the mob trait list in VV + MTandi: + - qol: new uplink UI + - qol: made it possible to buy a custom amount of TC, instead of bundles with fixed + amounts + Majkl-J: + - bugfix: Flashdarks now broduce darkness upon toggling + SmArtKar: + - bugfix: Bamboo staves can now be wielded + - bugfix: Bostaff no longer disappears forever when wielded + - bugfix: Rice hat no longer disappears upon being toggled and can be raised back + up. Toggling sprites is now done by alt-clicking + - qol: Callouts and MODsuit quick module pickers now track user + - qol: Cable coil and welding tool healing now loops similarly to sutures/meshes + - bugfix: Fixed cable coil/welding tool heal message not displaying when healing + someone else + - bugfix: Putting people you're fireman carrying into contractor pods no longer + sends both of you to zelda's shadow realm + Tattle: + - qol: dead cyborgs now blink yellow lights + - qol: damaged cyborgs have smoke particles when they've taken brute damage, and + sparks for burn + Y0SH1M4S73R: + - admin: The layout of the lua editor has been tweaked slightly. + - admin: In the lua editor, you can now toggle whether to log runtimes the viewed + state is involved in. + carlarctg: + - rscadd: Adds a bronze dimensional theme + necromanceranne: + - bugfix: Shoving someone onto a table now causes them to become vulnerable to being + stunned. diff --git a/icons/mob/silicon/robots.dmi b/icons/mob/silicon/robots.dmi index 5c79a0f95e39bd..c2780ce26abea7 100644 Binary files a/icons/mob/silicon/robots.dmi and b/icons/mob/silicon/robots.dmi differ diff --git a/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx b/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx index e64673ed5a5968..078f3e8026fa89 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoMalf.tsx @@ -183,6 +183,8 @@ export const AntagInfoMalf = (props) => { items.push({ id: item.name, name: item.name, + icon: item.icon, + icon_state: item.icon_state, category: category.name, cost: `${item.cost} PT`, desc: item.desc, diff --git a/tgui/packages/tgui/interfaces/LuaEditor/Log.tsx b/tgui/packages/tgui/interfaces/LuaEditor/Log.tsx index b4f2b82bb3e9f6..be0730a350df11 100644 --- a/tgui/packages/tgui/interfaces/LuaEditor/Log.tsx +++ b/tgui/packages/tgui/interfaces/LuaEditor/Log.tsx @@ -120,8 +120,8 @@ export const Log = (props: LogProps) => { }` : ''} . - - {return_values.length ? ( + {return_values.length ? ( + { }) } /> - ) : ( -
- )} -
+
+ ) : ( +
+ )} ); messageColor = 'green'; @@ -187,7 +187,7 @@ export const Log = (props: LogProps) => { if (chunk) { output = ( <> - {output} + {output}