diff --git a/_maps/map_files/moonstation/moonstation.dmm b/_maps/map_files/moonstation/moonstation.dmm index 883061007c4..8a797eefe71 100644 --- a/_maps/map_files/moonstation/moonstation.dmm +++ b/_maps/map_files/moonstation/moonstation.dmm @@ -71459,9 +71459,12 @@ /turf/closed/wall/r_wall/rust, /area/moonstation/underground) "tFI" = ( -/obj/structure/tram, +/obj/structure/fluff/tram_rail/electric{ + dir = 1 + }, /obj/structure/transport/linear/tram, -/obj/structure/plaque/static_plaque/tram{ +/obj/structure/thermoplastic, +/obj/structure/sign/tram_plate/directional/south{ specific_transport_id = "moon_1" }, /turf/open/floor/plating, @@ -222519,8 +222522,8 @@ iiB sqG iWG eNL -iMX tFI +sDL tHD asy wpy diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 67f163d271c..e4571ea105b 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -37296,6 +37296,7 @@ }, /obj/structure/transport/linear/tram, /obj/structure/thermoplastic, +/obj/structure/sign/tram_plate/directional/south, /turf/open/openspace, /area/station/hallway/primary/tram/center) "may" = ( @@ -39729,12 +39730,6 @@ /obj/effect/turf_decal/trimline/blue/filled/line, /turf/open/floor/iron/white, /area/station/medical/surgery/fore) -"mXi" = ( -/obj/structure/transport/linear/tram, -/obj/structure/tram, -/obj/structure/plaque/static_plaque/tram, -/turf/open/openspace, -/area/station/hallway/primary/tram/center) "mXo" = ( /obj/structure/kitchenspike, /obj/effect/turf_decal/weather/snow, @@ -170305,7 +170300,7 @@ oKm uzl xBS mar -mXi +oKm dhI lej fxs diff --git a/code/__DEFINES/dcs/signals/signals_transport.dm b/code/__DEFINES/dcs/signals/signals_transport.dm index 6e3dc6f39b2..baa4e2ca1ff 100644 --- a/code/__DEFINES/dcs/signals/signals_transport.dm +++ b/code/__DEFINES/dcs/signals/signals_transport.dm @@ -4,6 +4,9 @@ /// Sent from /obj/structure/transport/linear/tram when it hits someone: () #define COMSIG_TRAM_COLLISION "tram_collided" +/// Sent from a mob that just got hit by the tram +#define COMSIG_LIVING_HIT_BY_TRAM "tram_hit_me" + // Sent to and from SStransport for control between various components /// Requesting transport move to a destination #define COMSIG_TRANSPORT_REQUEST "!REQ" diff --git a/code/__DEFINES/electrified_buckle.dm b/code/__DEFINES/electrified_buckle.dm index 59fab13ccba..725750ef439 100644 --- a/code/__DEFINES/electrified_buckle.dm +++ b/code/__DEFINES/electrified_buckle.dm @@ -8,6 +8,8 @@ #define SHOCK_REQUIREMENT_PARENT_MOB_ISALIVE (1<<3) ///a signal can toggle the ability to shock on a timer #define SHOCK_REQUIREMENT_SIGNAL_RECEIVED_TOGGLE (1<<4) +///electrified buckle requires the area to be powered but not necessarily connected by cable +#define SHOCK_REQUIREMENT_AREA_POWER (1<<5) ///This trait signifies that the object can be used to electrify things buckled to it diff --git a/code/datums/components/electrified_buckle.dm b/code/datums/components/electrified_buckle.dm index f0a5ab85791..31610be8f08 100644 --- a/code/datums/components/electrified_buckle.dm +++ b/code/datums/components/electrified_buckle.dm @@ -20,12 +20,20 @@ var/usage_flags ///if true, this will shock the buckled mob every shock_loop_time in process() var/shock_on_loop = TRUE + ///if true we zap the buckled mob as soon as it becomes buckled + var/shock_immediately = FALSE + ///do we output a message every time someone gets shocked? + var/print_message = TRUE ///how long the component waits before shocking the mob buckled to parent again var/shock_loop_time = 5 SECONDS ///how much damage is done per shock iff usage_flags doesnt have SHOCK_REQUIREMENT_LIVE_CABLE var/shock_damage = 50 ///this signal was given as an argument to register for parent to emit, if its emitted to parent then shock_on_demand is called. var is so it can be unregistered var/requested_signal_parent_emits = null + ///what area power channel do we check if area power is required? + var/area_power_channel = AREA_USAGE_EQUIP + ///details of how we electrocute people + var/shock_flags /** * Initialize args: @@ -35,14 +43,22 @@ * * overlays_to_add - pass in a list of images and the component will add them to parent as well as remove them in UnregisterFromParent(). sets requested_overlays * * override_buckle - if TRUE, sets parent.can_buckle = TRUE and resets it on UnregisterFromParent(), usually objects that have need to be overridden will look janky on buckle * * damage_on_shock - if SHOCK_REQUIREMENT_LIVE_CABLE is not set in input_requirements, then this is how much damage each shock does. sets shock_damage + * * shock_immediately - if TRUE we will shock the buckled mob the first time we process after buckling, otherwise we wait until the cooldown has passed + * * print_message - if TRUE we will show a message every time we electrocute someone during the shock loop * * signal_to_register_from_parent - if set, the component registers to listen for this signal targeting parent to manually shock. sets requested_signal_parent_emits + * * area_power_channel - if SHOCK_REQUIREMENT_AREA_POWER is set in input_requirements, it will check this power channel in the area + * * shock_flags - flags passed into electrocute_act when we zap someone */ -/datum/component/electrified_buckle/Initialize(input_requirements, obj/item/input_item, list/overlays_to_add, override_buckle, damage_on_shock = 50, signal_to_register_from_parent, loop_length) +/datum/component/electrified_buckle/Initialize(input_requirements, obj/item/input_item, list/overlays_to_add, override_buckle = FALSE, damage_on_shock = 50, shock_immediately = FALSE, print_message = TRUE, signal_to_register_from_parent, loop_length, area_power_channel, shock_flags = NONE) var/atom/movable/parent_as_movable = parent if(!istype(parent_as_movable)) return COMPONENT_INCOMPATIBLE usage_flags = input_requirements + src.shock_immediately = shock_immediately + src.print_message = print_message + src.area_power_channel = area_power_channel + src.shock_flags = shock_flags if(!parent_as_movable.can_buckle && !override_buckle) return COMPONENT_INCOMPATIBLE @@ -63,7 +79,7 @@ if(usage_flags & SHOCK_REQUIREMENT_ON_SIGNAL_RECEIVED) shock_on_loop = FALSE - RegisterSignal(required_object, COMSIG_ASSEMBLY_PULSED, PROC_REF(shock_on_demand)) + RegisterSignal(required_object, COMSIG_ASSEMBLY_PULSED, PROC_REF(do_electrocution)) else if(usage_flags & SHOCK_REQUIREMENT_SIGNAL_RECEIVED_TOGGLE) RegisterSignal(required_object, COMSIG_ASSEMBLY_PULSED, PROC_REF(toggle_shock_loop)) @@ -78,7 +94,7 @@ //if parent wants us to manually shock on some specified action if(signal_to_register_from_parent) - RegisterSignal(parent, signal_to_register_from_parent, PROC_REF(shock_on_demand)) + RegisterSignal(parent, signal_to_register_from_parent, PROC_REF(do_electrocution)) requested_signal_parent_emits = signal_to_register_from_parent if(overlays_to_add) @@ -137,6 +153,9 @@ if (requested_overlays) source.update_appearance() + if (shock_immediately) + do_electrocution() + COOLDOWN_START(src, electric_buckle_cooldown, shock_loop_time) if(!(usage_flags & SHOCK_REQUIREMENT_ON_SIGNAL_RECEIVED) && shock_on_loop) START_PROCESSING(SSprocessing, src) @@ -171,31 +190,20 @@ return COOLDOWN_START(src, electric_buckle_cooldown, shock_loop_time) + do_electrocution() - var/turf/our_turf = get_turf(parent_as_movable) - var/obj/structure/cable/live_cable = our_turf.get_cable_node() + if (print_message) + parent_as_movable.visible_message(span_danger("[parent_as_movable] delivers a powerful shock!"), span_hear("You hear a deep sharp shock!")) - if(usage_flags & SHOCK_REQUIREMENT_LIVE_CABLE) - if((!live_cable || !live_cable.powernet || live_cable.powernet.avail < ELECTRIC_BUCKLE_MINUMUM_POWERNET_STRENGTH)) - return - - for(var/mob/living/guinea_pig as anything in parent_as_movable.buckled_mobs) - guinea_pig.electrocute_act(round(live_cable.powernet.avail / ELECTRIC_BUCKLE_SHOCK_STRENGTH_DIVISOR), parent_as_movable) - break - else - for(var/mob/living/guinea_pig as anything in parent_as_movable.buckled_mobs) - guinea_pig.electrocute_act(shock_damage, parent_as_movable) - break - - parent_as_movable.visible_message(span_danger("The electric chair went off!"), span_hear("You hear a deep sharp shock!")) - -///a shock that is toggled manually -/datum/component/electrified_buckle/proc/shock_on_demand() +/// Zap whoever is buckled to us +/datum/component/electrified_buckle/proc/do_electrocution() SIGNAL_HANDLER + if((usage_flags & SHOCK_REQUIREMENT_ITEM) && QDELETED(required_object)) return var/atom/movable/parent_as_movable = parent + if(usage_flags & SHOCK_REQUIREMENT_LIVE_CABLE) var/turf/our_turf = get_turf(parent_as_movable) var/obj/structure/cable/live_cable = our_turf.get_cable_node() @@ -204,8 +212,22 @@ for(var/mob/living/guinea_pig as anything in parent_as_movable.buckled_mobs) var/shock_damage = round(live_cable.powernet.avail / ELECTRIC_BUCKLE_SHOCK_STRENGTH_DIVISOR) - guinea_pig.electrocute_act(shock_damage, parent_as_movable) - break + guinea_pig.electrocute_act(shock_damage, parent_as_movable, flags = shock_flags) + + return + + if(usage_flags & SHOCK_REQUIREMENT_AREA_POWER) + var/area/our_area = get_area(parent) + if (!our_area.powered(area_power_channel)) + return + + for(var/mob/living/guinea_pig as anything in parent_as_movable.buckled_mobs) + guinea_pig.electrocute_act(shock_damage, parent_as_movable, flags = shock_flags) + + return + + for(var/mob/living/guinea_pig as anything in parent_as_movable.buckled_mobs) + guinea_pig.electrocute_act(shock_damage, parent_as_movable, flags = shock_flags) /datum/component/electrified_buckle/proc/toggle_shock_loop() SIGNAL_HANDLER @@ -213,11 +235,11 @@ if(shock_on_loop) shock_on_loop = FALSE STOP_PROCESSING(SSprocessing, src) - parent_as_movable.visible_message(span_notice("The electric chair emits a snap as its circuit opens, making it safe for now.")) + parent_as_movable.visible_message(span_notice("\The [parent_as_movable] emits a snap as its circuit opens, making it safe for now.")) else shock_on_loop = TRUE START_PROCESSING(SSprocessing, src) - parent_as_movable.visible_message(span_notice("You hear the sound of an electric circuit closing coming from the electric chair!")) + parent_as_movable.visible_message(span_notice("You hear the sound of an electric circuit closing coming from \the [parent_as_movable]!")) #undef ELECTRIC_BUCKLE_SHOCK_STRENGTH_DIVISOR #undef ELECTRIC_BUCKLE_MINUMUM_POWERNET_STRENGTH diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm index 7acfa65f625..a383d9af234 100644 --- a/code/game/objects/structures/fluff.dm +++ b/code/game/objects/structures/fluff.dm @@ -289,6 +289,25 @@ plane = FLOOR_PLANE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF deconstructible = FALSE + can_buckle = TRUE + buckle_requires_restraints = TRUE + buckle_lying = 90 + +/obj/structure/fluff/tram_rail/post_buckle_mob(mob/living/target) + . = ..() + target.pixel_y += dir == SOUTH ? -3 : 14 + RegisterSignal(target, COMSIG_LIVING_HIT_BY_TRAM, PROC_REF(on_buckled_tram_smashed)) + +/obj/structure/fluff/tram_rail/post_unbuckle_mob(mob/living/target) + . = ..() + target.pixel_y -= dir == SOUTH ? -3 : 14 + UnregisterSignal(target, COMSIG_LIVING_HIT_BY_TRAM) + +/// If someone gets hit by the tram while buckled to us (mission accomplished) unbuckle them so that they can fly away +/// Also we rip one of their arms off to "uncuff" them +/obj/structure/fluff/tram_rail/proc/on_buckled_tram_smashed(mob/living/smashed) + SIGNAL_HANDLER + unbuckle_mob(smashed, force = TRUE, can_fall = FALSE) // Make sure they don't fall down a z-level until they've been thrown /obj/structure/fluff/tram_rail/floor name = "tram rail protective cover" @@ -297,19 +316,36 @@ /obj/structure/fluff/tram_rail/end icon_state = "railend" -/obj/structure/fluff/tram_rail/electric - desc = "Great for trams, not so great for skating. This one is a power rail." - /obj/structure/fluff/tram_rail/anchor name = "tram rail anchor" icon_state = "anchor" +/obj/structure/fluff/tram_rail/electric + desc = "Great for trams, not so great for skating. This one is a power rail." + /// What power channel from the APC do we check for power? + var/power_channel = AREA_USAGE_ENVIRON + /obj/structure/fluff/tram_rail/electric/anchor name = "tram rail anchor" icon_state = "anchor" +/obj/structure/fluff/tram_rail/electric/Initialize(mapload) + . = ..() + AddComponent(\ + /datum/component/electrified_buckle,\ + input_requirements = SHOCK_REQUIREMENT_AREA_POWER,\ + shock_immediately = TRUE,\ + print_message = FALSE,\ + damage_on_shock = 5,\ + loop_length = 8 SECONDS,\ + area_power_channel = power_channel,\ + shock_flags = SHOCK_NOSTUN\ + ) + /obj/structure/fluff/tram_rail/electric/attack_hand(mob/living/user, list/modifiers) - if(user.electrocute_act(75, src)) + . = ..() + var/area/our_area = get_area(src) + if(our_area?.powered(power_channel) && user.electrocute_act(75, src)) do_sparks(5, TRUE, src) /obj/structure/fluff/broken_canister_frame diff --git a/code/game/objects/structures/plaques/static_plaques.dm b/code/game/objects/structures/plaques/static_plaques.dm index c13cf832ab2..53e1cbb3198 100644 --- a/code/game/objects/structures/plaques/static_plaques.dm +++ b/code/game/objects/structures/plaques/static_plaques.dm @@ -25,83 +25,6 @@ /obj/structure/plaque/static_plaque/golden/captain name = "The Most Robust Captain Award for Robustness" -/obj/structure/plaque/static_plaque/tram - /// The tram we have info about - var/specific_transport_id = TRAMSTATION_LINE_1 - /// Weakref to the tram we have info about - var/datum/weakref/transport_ref - /// Serial number of the tram - var/tram_serial - name = "\improper tram information plate" - icon_state = "commission_tram" - custom_materials = list(/datum/material/titanium = SHEET_MATERIAL_AMOUNT) - layer = SIGN_LAYER - -/obj/structure/plaque/static_plaque/tram/Initialize(mapload) - . = ..() - return INITIALIZE_HINT_LATELOAD - -/obj/structure/plaque/static_plaque/tram/LateInitialize() - link_tram() - set_tram_serial() - -/obj/structure/plaque/static_plaque/tram/add_context(atom/source, list/context, obj/item/held_item, mob/user) - . = ..() - if(isnull(held_item)) - context[SCREENTIP_CONTEXT_LMB] = "View details" - return CONTEXTUAL_SCREENTIP_SET - -/obj/structure/plaque/static_plaque/tram/proc/link_tram() - for(var/datum/transport_controller/linear/tram/tram as anything in SStransport.transports_by_type[TRANSPORT_TYPE_TRAM]) - if(tram.specific_transport_id == specific_transport_id) - transport_ref = WEAKREF(tram) - break - -/obj/structure/plaque/static_plaque/tram/proc/set_tram_serial() - var/datum/transport_controller/linear/tram/tram = transport_ref?.resolve() - if(isnull(tram) || isnull(tram.tram_registration)) - return - - tram_serial = tram.tram_registration.serial_number - desc = "A plate showing details from the manufacturer about this Nakamura Engineering SkyyTram Mk VI, serial number [tram_serial].

We are not responsible for any injuries or fatalities caused by usage of the tram. \ - Using the tram carries inherent risks, and we cannot guarantee the safety of all passengers. By using the tram, you assume, acknowledge, and accept all the risks and responsibilities.

\ - Please be aware that riding the tram can cause a variety of injuries, including but not limited to: slips, trips, and falls; collisions with other passengers or objects; strains, sprains, and other musculoskeletal injuries; \ - cuts, bruises, and lacerations; and more severe injuries such as head trauma, spinal cord injuries, and even death. These injuries can be caused by a variety of factors, including the movements of the tram, the behaviour \ - of other passengers, and unforeseen circumstances such as foul play or mechanical issues.

\ - By entering the tram, guideway, or crossings you agree Nanotrasen is not liable for any injuries, damages, or losses that may occur. If you do not agree to these terms, please do not use the tram.
" - -/obj/structure/plaque/static_plaque/tram/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "TramPlaque") - ui.autoupdate = FALSE - ui.open() - -/obj/structure/plaque/static_plaque/tram/ui_static_data(mob/user) - var/datum/transport_controller/linear/tram/tram = transport_ref?.resolve() - var/list/data = list() - var/list/current_tram = list() - var/list/previous_trams = list() - - current_tram += list(list( - "serialNumber" = tram.tram_registration.serial_number, - "mfgDate" = tram.tram_registration.mfg_date, - "distanceTravelled" = tram.tram_registration.distance_travelled, - "tramCollisions" = tram.tram_registration.collisions, - )) - - for(var/datum/tram_mfg_info/previous_tram as anything in tram.tram_history) - previous_trams += list(list( - "serialNumber" = previous_tram.serial_number, - "mfgDate" = previous_tram.mfg_date, - "distanceTravelled" = previous_tram.distance_travelled, - "tramCollisions" = previous_tram.collisions, - )) - - data["currentTram"] = current_tram - data["previousTrams"] = previous_trams - return data - // Commission plaques, to give a little backstory to the stations. Commission dates are date of merge (or best approximation, in the case of Meta) + 540 years to convert to SS13 dates. // Where PRs are available, I've linked them. Where they are unavailable, a git hash is provided instead for the direct commit that added/removed the map. // Please enjoy this trip through SS13's history. diff --git a/code/game/objects/structures/signs/_signs.dm b/code/game/objects/structures/signs/_signs.dm index d3713ca1b2f..d8371768442 100644 --- a/code/game/objects/structures/signs/_signs.dm +++ b/code/game/objects/structures/signs/_signs.dm @@ -210,7 +210,7 @@ return ..() /obj/item/sign/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) - if(!iswallturf(interacting_with)) + if(!iswallturf(interacting_with) && !istype(interacting_with, /obj/structure/tram)) return NONE var/turf/target_turf = interacting_with var/turf/user_turf = get_turf(user) diff --git a/code/game/objects/structures/signs/signs_misc.dm b/code/game/objects/structures/signs/signs_misc.dm index 0b0348977df..6825063c95e 100644 --- a/code/game/objects/structures/signs/signs_misc.dm +++ b/code/game/objects/structures/signs/signs_misc.dm @@ -27,3 +27,85 @@ desc = "85cr for a iced lactose-free caramel frappe?! Who buys that?!" MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/xenobio_guide, 32) + +// Tram-mounted statistics plate +/obj/structure/sign/tram_plate + /// The tram we have info about + var/specific_transport_id = TRAMSTATION_LINE_1 + /// Weakref to the tram we have info about + var/datum/weakref/transport_ref + /// Serial number of the tram + var/tram_serial + name = "tram information plate" + sign_change_name = "Information - Tram Statistics" + icon_state = "commission_tram" + max_integrity = 150 + armor_type = /datum/armor/tram_structure + is_editable = FALSE + +/obj/structure/sign/tram_plate/Initialize(mapload) + . = ..() + return INITIALIZE_HINT_LATELOAD + +/obj/structure/sign/tram_plate/LateInitialize() + link_tram() + set_tram_serial() + +/obj/structure/sign/tram_plate/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + if(isnull(held_item)) + context[SCREENTIP_CONTEXT_LMB] = "View details" + return CONTEXTUAL_SCREENTIP_SET + +/obj/structure/sign/tram_plate/proc/link_tram() + for(var/datum/transport_controller/linear/tram/tram as anything in SStransport.transports_by_type[TRANSPORT_TYPE_TRAM]) + if(tram.specific_transport_id == specific_transport_id) + transport_ref = WEAKREF(tram) + break + +/obj/structure/sign/tram_plate/proc/set_tram_serial() + var/datum/transport_controller/linear/tram/tram = transport_ref?.resolve() + if(isnull(tram) || isnull(tram.tram_registration)) + return + + tram_serial = tram.tram_registration.serial_number + desc = "A plate showing details from the manufacturer about this Nakamura Engineering SkyyTram Mk VI, serial number [tram_serial].

We are not responsible for any injuries or fatalities caused by usage of the tram. \ + Using the tram carries inherent risks, and we cannot guarantee the safety of all passengers. By using the tram, you assume, acknowledge, and accept all the risks and responsibilities.

\ + Please be aware that riding the tram can cause a variety of injuries, including but not limited to: slips, trips, and falls; collisions with other passengers or objects; strains, sprains, and other musculoskeletal injuries; \ + cuts, bruises, and lacerations; and more severe injuries such as head trauma, spinal cord injuries, and even death. These injuries can be caused by a variety of factors, including the movements of the tram, the behaviour \ + of other passengers, and unforeseen circumstances such as foul play or mechanical issues.

\ + By entering the tram, guideway, or crossings you agree Nanotrasen is not liable for any injuries, damages, or losses that may occur. If you do not agree to these terms, please do not use the tram.
" + +/obj/structure/sign/tram_plate/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TramPlaque") + ui.autoupdate = FALSE + ui.open() + +/obj/structure/sign/tram_plate/ui_static_data(mob/user) + var/datum/transport_controller/linear/tram/tram = transport_ref?.resolve() + var/list/data = list() + var/list/current_tram = list() + var/list/previous_trams = list() + + current_tram += list(list( + "serialNumber" = tram.tram_registration.serial_number, + "mfgDate" = tram.tram_registration.mfg_date, + "distanceTravelled" = tram.tram_registration.distance_travelled, + "tramCollisions" = tram.tram_registration.collisions, + )) + + for(var/datum/tram_mfg_info/previous_tram as anything in tram.tram_history) + previous_trams += list(list( + "serialNumber" = previous_tram.serial_number, + "mfgDate" = previous_tram.mfg_date, + "distanceTravelled" = previous_tram.distance_travelled, + "tramCollisions" = previous_tram.collisions, + )) + + data["currentTram"] = current_tram + data["previousTrams"] = previous_trams + return data + +MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/tram_plate, 32) diff --git a/code/modules/transport/transport_module.dm b/code/modules/transport/transport_module.dm index 83fd824bd6a..26295edbe0b 100644 --- a/code/modules/transport/transport_module.dm +++ b/code/modules/transport/transport_module.dm @@ -417,9 +417,11 @@ var/extra_ouch = FALSE // if emagged you're gonna have a really bad time if(speed_limiter == 0.5) // slow trams don't cause extra damage for(var/obj/structure/tram/spoiler/my_spoiler in transport_contents) + if(istype(victim_living.buckled, /obj/structure/fluff/tram_rail)) + extra_ouch = TRUE + break if(get_dist(my_spoiler, victim_living) != 1) continue - if(my_spoiler.deployed) extra_ouch = TRUE break @@ -427,31 +429,31 @@ if(transport_controller_datum.ignored_smashthroughs[victim_living.type]) continue to_chat(victim_living, span_userdanger("[src] collides into you!")) + SEND_SIGNAL(victim_living, COMSIG_LIVING_HIT_BY_TRAM, src) playsound(src, 'sound/effects/splat.ogg', 50, TRUE) var/damage = 0 - switch(extra_ouch) - if(TRUE) - playsound(src, 'sound/effects/grillehit.ogg', 50, TRUE) - var/obj/item/bodypart/head/head = victim_living.get_bodypart("head") - if(head) - log_combat(src, victim_living, "beheaded") - head.dismember() - victim_living.regenerate_icons() - add_overlay(mutable_appearance(icon, "blood_overlay")) - register_collision(points = 3) - if(FALSE) - log_combat(src, victim_living, "collided with") - if(prob(15)) //sorry buddy, luck wasn't on your side - damage = 29 * collision_lethality * damage_multiplier - else - damage = rand(7, 21) * collision_lethality * damage_multiplier - victim_living.apply_damage(2 * damage, BRUTE, BODY_ZONE_HEAD, wound_bonus = 7) - victim_living.apply_damage(3 * damage, BRUTE, BODY_ZONE_CHEST, wound_bonus = 21) - victim_living.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_L_LEG, wound_bonus = 14) - victim_living.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_R_LEG, wound_bonus = 14) - victim_living.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_L_ARM, wound_bonus = 14) - victim_living.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_R_ARM, wound_bonus = 14) + log_combat(src, victim_living, "collided with") + if(prob(15)) //sorry buddy, luck wasn't on your side + damage = 29 * collision_lethality * damage_multiplier + else + damage = rand(7, 21) * collision_lethality * damage_multiplier + victim_living.apply_damage(2 * damage, BRUTE, BODY_ZONE_HEAD, wound_bonus = 7) + victim_living.apply_damage(3 * damage, BRUTE, BODY_ZONE_CHEST, wound_bonus = 21) + victim_living.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_L_LEG, wound_bonus = 14) + victim_living.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_R_LEG, wound_bonus = 14) + victim_living.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_L_ARM, wound_bonus = 14) + victim_living.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_R_ARM, wound_bonus = 14) + + if (extra_ouch) + playsound(src, 'sound/effects/grillehit.ogg', 50, TRUE) + var/obj/item/bodypart/head/head = victim_living.get_bodypart("head") + if(head) + log_combat(src, victim_living, "beheaded") + head.dismember() + victim_living.regenerate_icons() + add_overlay(mutable_appearance(icon, "blood_overlay")) + register_collision(points = 3) if(QDELETED(victim_living)) //in case it was a mob that dels on death continue diff --git a/html/changelogs/AutoChangeLog-pr-90293.yml b/html/changelogs/AutoChangeLog-pr-90293.yml new file mode 100644 index 00000000000..7e7183f5069 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-90293.yml @@ -0,0 +1,5 @@ +author: "Jacquerel" +delete-after: True +changes: + - rscadd: "Handcuffed people can now be tied to the tram rails" + - balance: "tram rails will no longer electrocute you if they're not powered" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-90311.yml b/html/changelogs/AutoChangeLog-pr-90311.yml new file mode 100644 index 00000000000..a49cd2ec80a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-90311.yml @@ -0,0 +1,4 @@ +author: "LT3" +delete-after: True +changes: + - bugfix: "Tram information plate and other signs mount correctly on tram walls" \ No newline at end of file diff --git a/icons/hud/screen_alert.dmi b/icons/hud/screen_alert.dmi index 2d12bdd0151..b9f00a606c9 100755 Binary files a/icons/hud/screen_alert.dmi and b/icons/hud/screen_alert.dmi differ