mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-30 08:29:57 +01:00
Merge branch 'Aurorastation:master' into boneyard
This commit is contained in:
@@ -370,6 +370,9 @@ Class Procs:
|
||||
attack_hand(user)
|
||||
|
||||
/obj/structure/machinery/attackby(obj/item/attacking_item, mob/user)
|
||||
if(default_part_replacement(user, attacking_item))
|
||||
return TRUE
|
||||
|
||||
if(obj_flags & OBJ_FLAG_SIGNALER)
|
||||
if(issignaler(attacking_item))
|
||||
if(signaler)
|
||||
@@ -488,23 +491,43 @@ Class Procs:
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/machinery/proc/get_part_replacement_type(obj/item/part)
|
||||
var/obj/item/circuitboard/board = locate(/obj/item/circuitboard) in component_parts
|
||||
var/replacement_type
|
||||
|
||||
if(board?.req_components)
|
||||
for(var/component_type in board.req_components)
|
||||
var/board_part_type = ispath(component_type) ? component_type : text2path(component_type)
|
||||
if(!ispath(board_part_type, /obj/item/stock_parts) && !ispath(board_part_type, /obj/item/reagent_containers/glass))
|
||||
continue
|
||||
if(istype(part, board_part_type) && (!replacement_type || ispath(board_part_type, replacement_type)))
|
||||
replacement_type = board_part_type
|
||||
|
||||
if(replacement_type)
|
||||
return replacement_type
|
||||
|
||||
for(var/component_type in component_types)
|
||||
var/component_part_type = ispath(component_type) ? component_type : text2path(component_type)
|
||||
if(!ispath(component_part_type, /obj/item/stock_parts) && !ispath(component_part_type, /obj/item/reagent_containers/glass))
|
||||
continue
|
||||
if(istype(part, component_part_type) && (!replacement_type || ispath(component_part_type, replacement_type)))
|
||||
replacement_type = component_part_type
|
||||
|
||||
return replacement_type
|
||||
|
||||
/obj/structure/machinery/proc/default_part_replacement(var/mob/user, var/obj/item/storage/part_replacer/R)
|
||||
if(!LAZYLEN(component_parts))
|
||||
return FALSE
|
||||
else if(istype(R))
|
||||
var/parts_replaced = FALSE
|
||||
if(panel_open)
|
||||
var/obj/item/circuitboard/CB = locate(/obj/item/circuitboard) in component_parts
|
||||
var/P
|
||||
for(var/obj/item/reagent_containers/glass/G in component_parts)
|
||||
for(var/D in CB.req_components)
|
||||
var/T = text2path(D)
|
||||
if(ispath(G.type, T))
|
||||
P = T
|
||||
break
|
||||
var/replacement_type = get_part_replacement_type(G)
|
||||
if(!replacement_type)
|
||||
continue
|
||||
for(var/obj/item/reagent_containers/glass/B in R.contents)
|
||||
if(B.reagents && B.reagents.total_volume > 0) continue
|
||||
if(istype(B, P) && istype(G, P))
|
||||
if(istype(B, replacement_type))
|
||||
if(B.volume > G.volume)
|
||||
R.remove_from_storage(B, src)
|
||||
R.handle_item_insertion(G, 1)
|
||||
@@ -512,15 +535,14 @@ Class Procs:
|
||||
component_parts += B
|
||||
B.forceMove(src)
|
||||
to_chat(user, SPAN_NOTICE("[G.name] replaced with [B.name]."))
|
||||
parts_replaced = TRUE
|
||||
break
|
||||
for(var/obj/item/stock_parts/A in component_parts)
|
||||
for(var/D in CB.req_components)
|
||||
var/T = text2path(D)
|
||||
if(ispath(A.type, T))
|
||||
P = T
|
||||
break
|
||||
var/replacement_type = get_part_replacement_type(A)
|
||||
if(!replacement_type)
|
||||
continue
|
||||
for(var/obj/item/stock_parts/B in R.contents)
|
||||
if(istype(B, P) && istype(A, P))
|
||||
if(istype(B, replacement_type))
|
||||
if(B.rating > A.rating)
|
||||
R.remove_from_storage(B, src)
|
||||
R.handle_item_insertion(A, 1)
|
||||
@@ -530,9 +552,9 @@ Class Procs:
|
||||
to_chat(user, SPAN_NOTICE("[A.name] replaced with [B.name]."))
|
||||
parts_replaced = TRUE
|
||||
break
|
||||
RefreshParts()
|
||||
update_icon()
|
||||
if(parts_replaced) //only play sound when RPED actually replaces parts
|
||||
if(parts_replaced)
|
||||
RefreshParts()
|
||||
update_icon()
|
||||
playsound(src, 'sound/items/rped.ogg', 40, TRUE)
|
||||
return TRUE
|
||||
else
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
density = TRUE
|
||||
atom_flags = ATOM_FLAG_CHECKS_BORDER
|
||||
maxhealth = OBJECT_HEALTH_LOW
|
||||
pass_flags_self = LETPASSTHROW
|
||||
/// The type of stack the barricade dropped when disassembled if any.
|
||||
var/stack_type
|
||||
/// The amount of stack dropped when disassembled at full health
|
||||
@@ -83,11 +84,11 @@
|
||||
AddOverlays(image('icons/obj/barricades.dmi', icon_state = "[src.barricade_type]_closed_wire"))
|
||||
|
||||
..()
|
||||
|
||||
/obj/structure/barricade/proc/handle_barrier_chance()
|
||||
///Rolls a chance based on the percentage of the barricade's health remaining. Returns TRUE if the chance succeeds, FALSE if it fails. The chance is divided by the optional chance_divisor parameter, which defaults to 1.
|
||||
/obj/structure/barricade/proc/handle_barrier_chance(chance_divisor = 1)
|
||||
if(!anchored)
|
||||
return FALSE
|
||||
return prob(max(30,(100.0*health)/maxhealth))
|
||||
return prob(max(30,(100.0*health)/maxhealth) / chance_divisor)
|
||||
|
||||
/obj/structure/barricade/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(mover?.movement_type & PHASING)
|
||||
@@ -97,6 +98,16 @@
|
||||
if(istype(mover, /obj/projectile))
|
||||
return (check_cover(mover,target))
|
||||
if (get_dir(loc, target) == dir)
|
||||
if(mover.throwing)
|
||||
var/chance = (handle_barrier_chance(3))
|
||||
if(chance)
|
||||
visible_message(SPAN_WARNING("\The [mover] clips the top of \the [src] and bounces off!"))
|
||||
if(barricade_hitsound)
|
||||
playsound(src, barricade_hitsound, 20, 1)
|
||||
return !density
|
||||
else
|
||||
visible_message(SPAN_WARNING("\The [mover] sails over \the [src]!"))
|
||||
return TRUE
|
||||
return !density
|
||||
else
|
||||
return TRUE
|
||||
@@ -211,8 +222,6 @@
|
||||
return .
|
||||
|
||||
bullet_ping(hitting_projectile)
|
||||
var/damage_to_take = hitting_projectile.damage * hitting_projectile.anti_materiel_potential
|
||||
add_damage(damage_to_take, hitting_projectile.damage_flags(), hitting_projectile.damtype, hitting_projectile.armor_penetration, hitting_projectile)
|
||||
|
||||
/obj/structure/barricade/proc/barricade_deconstruct(deconstruct)
|
||||
if(deconstruct && is_wired)
|
||||
|
||||
@@ -357,8 +357,6 @@
|
||||
for(var/mob/living/L in contents)
|
||||
hitting_projectile.Impact(L)
|
||||
|
||||
damage(proj_damage)
|
||||
|
||||
/obj/structure/closet/attackby(obj/item/attacking_item, mob/user)
|
||||
if(istype(attacking_item, /obj/item/closet_teleporter))
|
||||
if(linked_teleporter)
|
||||
|
||||
@@ -126,7 +126,6 @@
|
||||
if(. != BULLET_ACT_HIT)
|
||||
return .
|
||||
|
||||
health -= hitting_projectile.get_structure_damage()
|
||||
check_health()
|
||||
|
||||
/obj/structure/closet/statue/attack_generic(mob/user, damage, attack_message, environment_smash, armor_penetration, attack_flags, damage_type)
|
||||
|
||||
@@ -797,3 +797,8 @@
|
||||
new /obj/item/storage/box/unique/tea/messa(src)
|
||||
new /obj/item/reagent_containers/toothpaste(src)
|
||||
new /obj/item/reagent_containers/food/drinks/flask/vacuumflask/mouthwash(src)
|
||||
|
||||
/obj/structure/closet/crate/tool/machinist/fill()
|
||||
new /obj/item/reagent_containers/weldpack(src)
|
||||
new /obj/item/portable_whiteboard(src)
|
||||
new /obj/item/paint_sprayer(src)
|
||||
|
||||
@@ -40,10 +40,6 @@
|
||||
if(. != BULLET_ACT_HIT)
|
||||
return .
|
||||
|
||||
var/damage = hitting_projectile.damage
|
||||
if(damage)
|
||||
add_damage(damage)
|
||||
|
||||
/obj/structure/displaycase/on_death()
|
||||
if(!destroyed)
|
||||
density = FALSE
|
||||
|
||||
@@ -171,7 +171,12 @@
|
||||
if(isfloor(user.loc))
|
||||
user.visible_message(SPAN_NOTICE("\The [user] deploys \the [src] on \the [get_turf(loc)]."), SPAN_NOTICE("You deploy \the [src] on \the [get_turf(loc)]."))
|
||||
user.drop_from_inventory(src)
|
||||
new flag_structure(user.loc, user.dir, deploy = TRUE, item_flag_path = flag_path)
|
||||
var/obj/structure/sign/flag/F = new flag_structure(user.loc, user.dir, deploy = TRUE, item_flag_path = flag_path)
|
||||
F.name = src.name
|
||||
F.desc = src.desc
|
||||
if(F.linked_flag)
|
||||
F.linked_flag.name = src.name
|
||||
F.linked_flag.desc = src.desc
|
||||
qdel(src)
|
||||
|
||||
/obj/item/flag/afterattack(var/atom/A, var/mob/user, var/adjacent)
|
||||
@@ -192,7 +197,12 @@
|
||||
|
||||
user.visible_message(SPAN_NOTICE("\The [user] fastens \the [src] to \the [A]."), SPAN_NOTICE("You fasten \the [src] to \the [A]."))
|
||||
user.drop_from_inventory(src)
|
||||
new flag_structure(user.loc, placement_dir, deploy = TRUE, item_flag_path = flag_path)
|
||||
var/obj/structure/sign/flag/F = new flag_structure(user.loc, user.dir, deploy = TRUE, item_flag_path = flag_path)
|
||||
F.name = src.name
|
||||
F.desc = src.desc
|
||||
if(F.linked_flag)
|
||||
F.linked_flag.name = src.name
|
||||
F.linked_flag.desc = src.desc
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -222,6 +232,8 @@
|
||||
else
|
||||
user.visible_message(SPAN_NOTICE("\The [user] unfastens \the [src] and folds it back up."), SPAN_NOTICE("You unfasten \the [src] and fold it back up."))
|
||||
var/obj/item/flag/F = new flag_item(get_turf(user))
|
||||
F.name = src.name
|
||||
F.desc = src.desc
|
||||
user.put_in_hands(F)
|
||||
else
|
||||
user.visible_message(SPAN_NOTICE("\The [user] unfastens the tattered remnants of \the [src]."), SPAN_NOTICE("You unfasten the tattered remains of \the [src]."))
|
||||
@@ -3719,6 +3731,58 @@
|
||||
/obj/structure/sign/flag/venus/large/west/Initialize(mapload)
|
||||
. = ..(mapload, WEST)
|
||||
|
||||
// Eris
|
||||
/obj/item/flag/eris
|
||||
name = "\improper Erisian Banner"
|
||||
desc = "The banner of the Sovereign Solarian Union of Eris and Dysnomia, a pair of distant dwarf worlds in the Sol System, dominated by the dual influence of the system’s largest communications array and the Solarian Navy."
|
||||
desc_extended = "The banner of Eris and Dysnomia features a bicolor of white and purple, separated by a gold stripe, with a golden ring and diamond at its center. Four purple stars are arranged along the top, while four white stars line the bottom.<br> \
|
||||
The white field evokes the planetoid’s isolation beyond the Kuiper Belt, while the purple pays tribute to the Solarian Navy and its significant influence on Erisian history. The gold stripe represents the vital flow of interstellar communication that passes through Eris. At the center, the golden emblem symbolizes the unity of Eris and Dysnomia: the circle for Eris, the diamond for Dysnomia, and the surrounding ring for their shared infrastructure and mutual dependence.<br> \
|
||||
The eight stars represent the primary habitats across the Union, four in purple for those on Eris and Dysnomia themselves, and four in white for the orbital habitats positioned among their Lagrange points."
|
||||
flag_path = "eris"
|
||||
flag_structure = /obj/structure/sign/flag/eris
|
||||
|
||||
/obj/structure/sign/flag/eris
|
||||
name = "\improper Erisian Banner"
|
||||
desc = "The banner of the Sovereign Solarian Union of Eris and Dysnomia, a pair of distant dwarf worlds in the Sol System, dominated by the dual influence of the system’s largest communications array and the Solarian Navy."
|
||||
desc_extended = "The banner of Eris and Dysnomia features a bicolor of white and purple, separated by a gold stripe, with a golden ring and diamond at its center. Four purple stars are arranged along the top, while four white stars line the bottom.<br> \
|
||||
The white field evokes the planetoid’s isolation beyond the Kuiper Belt, while the purple pays tribute to the Solarian Navy and its significant influence on Erisian history. The gold stripe represents the vital flow of interstellar communication that passes through Eris. At the center, the golden emblem symbolizes the unity of Eris and Dysnomia: the circle for Eris, the diamond for Dysnomia, and the surrounding ring for their shared infrastructure and mutual dependence.<br> \
|
||||
The eight stars represent the primary habitats across the Union, four in purple for those on Eris and Dysnomia themselves, and four in white for the orbital habitats positioned among their Lagrange points."
|
||||
flag_path = "eris"
|
||||
icon_state = "eris"
|
||||
flag_item = /obj/item/flag/eris
|
||||
|
||||
/obj/item/flag/eris/l
|
||||
name = "\improper Erisian Flag"
|
||||
desc = "The flag of the Sovereign Solarian Union of Eris and Dysnomia, a pair of distant dwarf worlds in the Sol System, dominated by the dual influence of the system’s largest communications array and the Solarian Navy."
|
||||
desc_extended = "The flag of Eris and Dysnomia features a bicolor of white and purple, separated by a gold stripe, with a golden ring and diamond at its center. Four purple stars are arranged along the top, while four white stars line the bottom.<br> \
|
||||
The white field evokes the planetoid’s isolation beyond the Kuiper Belt, while the purple pays tribute to the Solarian Navy and its significant influence on Erisian history. The gold stripe represents the vital flow of interstellar communication that passes through Eris. At the center, the golden emblem symbolizes the unity of Eris and Dysnomia: the circle for Eris, the diamond for Dysnomia, and the surrounding ring for their shared infrastructure and mutual dependence.<br> \
|
||||
The eight stars represent the primary habitats across the Union, four in purple for those on Eris and Dysnomia themselves, and four in white for the orbital habitats positioned among their Lagrange points."
|
||||
flag_size = TRUE
|
||||
flag_structure = /obj/structure/sign/flag/eris/large
|
||||
|
||||
/obj/structure/sign/flag/eris/large
|
||||
name = "\improper Erisian Flag"
|
||||
desc = "The flag of the Sovereign Solarian Union of Eris and Dysnomia, a pair of distant dwarf worlds in the Sol System, dominated by the dual influence of the system’s largest communications array and the Solarian Navy."
|
||||
desc_extended = "The flag of Eris and Dysnomia features a bicolor of white and purple, separated by a gold stripe, with a golden ring and diamond at its center. Four purple stars are arranged along the top, while four white stars line the bottom.<br> \
|
||||
The white field evokes the planetoid’s isolation beyond the Kuiper Belt, while the purple pays tribute to the Solarian Navy and its significant influence on Erisian history. The gold stripe represents the vital flow of interstellar communication that passes through Eris. At the center, the golden emblem symbolizes the unity of Eris and Dysnomia: the circle for Eris, the diamond for Dysnomia, and the surrounding ring for their shared infrastructure and mutual dependence.<br> \
|
||||
The eight stars represent the primary habitats across the Union, four in purple for those on Eris and Dysnomia themselves, and four in white for the orbital habitats positioned among their Lagrange points."
|
||||
icon_state = "eris_l"
|
||||
flag_path = "eris"
|
||||
flag_size = TRUE
|
||||
flag_item = /obj/item/flag/eris/l
|
||||
|
||||
/obj/structure/sign/flag/eris/large/north/Initialize(mapload)
|
||||
. = ..(mapload, NORTH)
|
||||
|
||||
/obj/structure/sign/flag/eris/large/south/Initialize(mapload)
|
||||
. = ..(mapload, SOUTH)
|
||||
|
||||
/obj/structure/sign/flag/eris/large/east/Initialize(mapload)
|
||||
. = ..(mapload, EAST)
|
||||
|
||||
/obj/structure/sign/flag/eris/large/west/Initialize(mapload)
|
||||
. = ..(mapload, WEST)
|
||||
|
||||
//Hiskyn
|
||||
/obj/item/flag/hiskyn
|
||||
name = "\improper Hiskyn's Revanchists flag"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
maxhealth = OBJECT_HEALTH_MEDIUM
|
||||
color = COLOR_GRAY20
|
||||
build_amt = 4
|
||||
pass_flags_self = PASSRAILING
|
||||
pass_flags_self = PASSRAILING | LETPASSTHROW
|
||||
layer = WINDOW_FRAME_LAYER
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
@@ -54,6 +54,10 @@
|
||||
return TRUE
|
||||
if(istype(mover, /obj/structure/closet/crate))
|
||||
return TRUE
|
||||
if(istype(mover,/obj/projectile))
|
||||
return TRUE
|
||||
if(mover.throwing)
|
||||
return TRUE
|
||||
if(istype(mover) && mover.pass_flags & PASSTABLE)
|
||||
return TRUE
|
||||
if(locate(/obj/structure/window_frame) in get_turf(mover))
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
/obj/structure/girder/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
|
||||
//Girders only provide partial cover. There's a chance that the projectiles will just pass through. (unless you are trying to shoot the girder)
|
||||
if(hitting_projectile.original != src && !prob(cover))
|
||||
return BULLET_ACT_HIT //pass through
|
||||
return BULLET_ACT_FORCE_PIERCE //pass through
|
||||
|
||||
var/damage = hitting_projectile.get_structure_damage()
|
||||
if(!damage)
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
if(. != BULLET_ACT_HIT)
|
||||
return .
|
||||
|
||||
add_damage(hitting_projectile.damage)
|
||||
|
||||
/obj/structure/gore/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
|
||||
@@ -96,8 +96,6 @@
|
||||
|
||||
bullet_ping(hitting_projectile)
|
||||
|
||||
health -= proj_damage
|
||||
|
||||
if(health <= 0)
|
||||
deflate(TRUE)
|
||||
return
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
density = TRUE
|
||||
light_system = MOVABLE_LIGHT
|
||||
maxhealth = OBJECT_HEALTH_LOW
|
||||
should_use_health = FALSE
|
||||
obj_flags = OBJ_FLAG_SIGNALER | OBJ_FLAG_CONDUCTABLE
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
|
||||
|
||||
@@ -157,8 +157,6 @@
|
||||
if(. != BULLET_ACT_HIT)
|
||||
return .
|
||||
|
||||
add_damage(hitting_projectile.get_structure_damage(), hitting_projectile.damage_flags(), hitting_projectile.damage_type, hitting_projectile.armor_penetration, hitting_projectile)
|
||||
|
||||
/obj/structure/machinery/camera/ex_act(severity)
|
||||
if(src.invuln)
|
||||
return
|
||||
@@ -381,14 +379,23 @@
|
||||
alarm_on = 0
|
||||
GLOB.camera_alarm.clearAlarm(loc, src)
|
||||
|
||||
//if false, then the camera is listed as DEACTIVATED and cannot be used
|
||||
/// If FALSE, then the camera is listed as DEACTIVATED and cannot be used
|
||||
/obj/structure/machinery/camera/proc/can_use()
|
||||
if(!status)
|
||||
return 0
|
||||
if(stat & (EMPED|BROKEN))
|
||||
return 0
|
||||
if(is_wireless_jammed())
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/// Only used below, but has separate proc for potential future use.
|
||||
/obj/structure/machinery/camera/proc/is_wireless_camera()
|
||||
return !isturf(loc)
|
||||
|
||||
/obj/structure/machinery/camera/proc/is_wireless_jammed()
|
||||
return is_wireless_camera() && get_turf(src) && within_jamming_range(src)
|
||||
|
||||
/obj/structure/machinery/camera/proc/can_see()
|
||||
var/list/see = null
|
||||
var/turf/pos = get_turf(src)
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
|
||||
state = 4
|
||||
var/obj/structure/machinery/camera/C = new(src.loc)
|
||||
QDEL_NULL(C.assembly)
|
||||
src.forceMove(C)
|
||||
C.assembly = src
|
||||
|
||||
@@ -106,6 +107,10 @@
|
||||
C.replace_networks(uniquelist(tempnetwork))
|
||||
|
||||
C.c_tag = input
|
||||
C.setPowerUsage()
|
||||
if(C.isMotion() && !(SSmachinery.processing[C]))
|
||||
START_PROCESSING_MACHINE(C, MACHINERY_PROCESS_SELF)
|
||||
C.update_coverage()
|
||||
|
||||
for(var/i = 5; i >= 0; i -= 1)
|
||||
var/direct = tgui_input_list(user, "Direction?", "Assembling Camera", list("Confirm", "NORTH", "EAST", "SOUTH", "WEST"))
|
||||
@@ -127,20 +132,35 @@
|
||||
return TRUE
|
||||
|
||||
// Upgrades!
|
||||
if(is_type_in_list(attacking_item, possible_upgrades) && !is_type_in_list(attacking_item, upgrades)) // Is a possible upgrade and isn't in the camera already.
|
||||
var/upgrade_type
|
||||
for(var/possible_upgrade in possible_upgrades)
|
||||
if(istype(attacking_item, possible_upgrade))
|
||||
upgrade_type = possible_upgrade
|
||||
break
|
||||
|
||||
if(upgrade_type)
|
||||
if(state != 3)
|
||||
to_chat(user, SPAN_WARNING("You need to wire the assembly before installing upgrades."))
|
||||
return TRUE
|
||||
if(locate(upgrade_type) in upgrades)
|
||||
to_chat(user, SPAN_WARNING("\The [src] already has that upgrade installed."))
|
||||
return TRUE
|
||||
if(istype(attacking_item, /obj/item/stock_parts/scanning_module))
|
||||
var/obj/item/stock_parts/scanning_module/SM = attacking_item
|
||||
if(SM.rating < 2)
|
||||
to_chat(user, SPAN_WARNING("That scanning module doesn't seem advanced enough."))
|
||||
return
|
||||
return TRUE
|
||||
to_chat(user, "You attach \the [attacking_item] into the assembly inner circuits.")
|
||||
upgrades += attacking_item
|
||||
user.remove_from_mob(attacking_item)
|
||||
attacking_item.forceMove(src)
|
||||
return
|
||||
return TRUE
|
||||
|
||||
// Taking out upgrades
|
||||
else if(attacking_item.tool_behaviour == TOOL_CROWBAR && upgrades.len)
|
||||
if(state != 3)
|
||||
to_chat(user, SPAN_WARNING("You need access to the wired circuits before removing upgrades."))
|
||||
return TRUE
|
||||
var/obj/U = locate(/obj) in upgrades
|
||||
if(U)
|
||||
to_chat(user, "You unattach an upgrade from the assembly.")
|
||||
|
||||
@@ -80,6 +80,9 @@ GLOBAL_LIST_INIT(engineering_networks, list(
|
||||
/obj/structure/machinery/camera/network/news
|
||||
network = list(NETWORK_NEWS)
|
||||
|
||||
/obj/structure/machinery/camera/network/expedition
|
||||
network = list(NETWORK_EXPEDITION)
|
||||
|
||||
// EMP
|
||||
|
||||
/obj/structure/machinery/camera/emp_proof/Initialize()
|
||||
|
||||
@@ -26,13 +26,23 @@
|
||||
camera_monitor_program = new("Compless")
|
||||
// Make sure that camera_monitor knows its been generated from a dedicated console; this will define its network access.
|
||||
camera_monitor_program.monitored_networks = console_networks
|
||||
camera_monitor_program.ntnet_endpoint = src
|
||||
camera_monitor_program.ntnet_endpoint_ethernet = TRUE
|
||||
|
||||
/obj/structure/machinery/computer/security/Destroy()
|
||||
reset_remote_viewers()
|
||||
if(camera_monitor_program)
|
||||
camera_monitor_program.reset_current()
|
||||
camera_monitor_program = null
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/structure/machinery/computer/security/proc/reset_remote_viewers()
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.machine == src && M.is_viewing_remote_view())
|
||||
M.unset_machine()
|
||||
M.reset_view(null)
|
||||
|
||||
/obj/structure/machinery/computer/security/attack_ai(var/mob/user as mob)
|
||||
if(!ai_can_interact(user))
|
||||
return
|
||||
@@ -41,6 +51,8 @@
|
||||
/obj/structure/machinery/computer/security/check_eye(var/mob/user as mob)
|
||||
if (user.stat || user.blinded || !operable())
|
||||
return -1
|
||||
if(camera_monitor_program?.current_camera)
|
||||
return camera_monitor_program.check_eye(user)
|
||||
if(!current_camera)
|
||||
return 0
|
||||
var/viewflag = current_camera.check_eye(user)
|
||||
@@ -51,6 +63,8 @@
|
||||
/obj/structure/machinery/computer/security/grants_equipment_vision(var/mob/user as mob)
|
||||
if(user.stat || user.blinded || !operable())
|
||||
return FALSE
|
||||
if(camera_monitor_program?.current_camera)
|
||||
return camera_monitor_program.grants_equipment_vision(user)
|
||||
if(!current_camera)
|
||||
return FALSE
|
||||
var/viewflag = current_camera.check_eye(user)
|
||||
@@ -91,7 +105,7 @@
|
||||
. = camera_monitor_program.ui_act(action, params, ui, state)
|
||||
|
||||
/obj/structure/machinery/computer/security/attack_hand(var/mob/user as mob)
|
||||
if (!(src.z in GetConnectedZlevels(starting_z_level)))
|
||||
if (!(src.z in GetConnectedZlevels(starting_z_level)) && !SSatlas.current_map.is_always_available_network_level(src.z))
|
||||
to_chat(user, "Unable to establish a connection.")
|
||||
return
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
@@ -115,9 +129,11 @@
|
||||
|
||||
if (user.stat || user.blinded || !operable())
|
||||
return 0
|
||||
if(!C.can_use())
|
||||
return 0
|
||||
set_current(C)
|
||||
|
||||
if (!(C.z in GetConnectedZlevels(starting_z_level)))
|
||||
if (!(C.z in GetConnectedZlevels(starting_z_level)) && !(SSatlas.current_map.is_always_available_network_level(src.z) && C.z == src.z))
|
||||
to_chat(user, SPAN_NOTICE("This camera is too far away to connect to!"))
|
||||
return FALSE
|
||||
|
||||
@@ -311,7 +327,7 @@
|
||||
req_access = list(150)
|
||||
|
||||
/obj/structure/machinery/computer/security/terminal
|
||||
name = "camera monitor terminal"
|
||||
name = "public camera monitor"
|
||||
icon = 'icons/obj/modular_computers/modular_terminal.dmi'
|
||||
icon_screen = "cameras"
|
||||
icon_keyboard = "security_key"
|
||||
@@ -320,3 +336,7 @@
|
||||
has_off_keyboards = TRUE
|
||||
can_pass_under = FALSE
|
||||
light_power_on = 1
|
||||
|
||||
/obj/structure/machinery/computer/security/terminal/public
|
||||
console_networks = list(NETWORK_EXPEDITION, NETWORK_NEWS)
|
||||
circuit = /obj/item/circuitboard/security/public
|
||||
|
||||
@@ -19,7 +19,10 @@ Deployable Kits
|
||||
density = TRUE
|
||||
layer = ABOVE_DOOR_LAYER // above door layer so it can appear on the airlocks like a proper barricade
|
||||
maxhealth = OBJECT_HEALTH_LOW
|
||||
|
||||
armor = list(
|
||||
MELEE = ARMOR_MELEE_RESISTANT,
|
||||
BULLET = ARMOR_BALLISTIC_PISTOL
|
||||
)
|
||||
var/force_material
|
||||
|
||||
/obj/structure/blocker/Initialize(mapload, var/material_name)
|
||||
@@ -46,13 +49,6 @@ Deployable Kits
|
||||
if(. != BULLET_ACT_HIT)
|
||||
return .
|
||||
|
||||
var/damage_modifier = 0.4
|
||||
switch(hitting_projectile.damage_type)
|
||||
if(DAMAGE_BURN)
|
||||
damage_modifier = 1
|
||||
if(DAMAGE_BRUTE)
|
||||
damage_modifier = 0.75
|
||||
health -= hitting_projectile.damage * damage_modifier
|
||||
if(!check_dismantle())
|
||||
visible_message(SPAN_WARNING("\The [src] is hit by \the [hitting_projectile]!"))
|
||||
|
||||
@@ -76,11 +72,6 @@ Deployable Kits
|
||||
return TRUE
|
||||
else
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
switch(attacking_item.damtype)
|
||||
if(DAMAGE_BURN)
|
||||
src.health -= attacking_item.force * 1
|
||||
if(DAMAGE_BRUTE)
|
||||
src.health -= attacking_item.force * 0.75
|
||||
shake_animation()
|
||||
playsound(src.loc, material.hitsound, attacking_item.get_clamped_volume(), 1)
|
||||
if(check_dismantle())
|
||||
@@ -280,7 +271,7 @@ Deployable Kits
|
||||
|
||||
/obj/item/deployable_kit/attack_self(mob/user)
|
||||
to_chat(user, SPAN_NOTICE("You start assembling \the [src]..."))
|
||||
if(do_after(user, assembly_time, src, DO_REPAIR_CONSTRUCT))
|
||||
if(do_after(user, assembly_time, src, DO_DEPLOY))
|
||||
assemble_kit(user)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -118,8 +118,6 @@
|
||||
var/door_frame_color = COLOR_GRAY20
|
||||
/// Color. The color of the stripe detail.
|
||||
var/stripe_color = null
|
||||
/// Color. The color of the symbol detail.
|
||||
var/symbol_color = null
|
||||
/// Color. The color of the window.
|
||||
var/window_color = null
|
||||
/// String (One of `MATERIAL_*`). The material used for the door's window if `glass` is set. Used to set `window_material` during init.
|
||||
@@ -523,6 +521,12 @@
|
||||
explosion_resistance = 20
|
||||
secured_wires = TRUE
|
||||
maxhealth = OBJECT_HEALTH_EXTREMELY_HIGH
|
||||
destroy_hits = 30
|
||||
armor = list(
|
||||
MELEE = ARMOR_MELEE_RESISTANT,
|
||||
BULLET = ARMOR_BALLISTIC_PISTOL,
|
||||
LASER = ARMOR_LASER_MEDIUM
|
||||
)
|
||||
features_powerloss_manual_override = FALSE
|
||||
ai_bolting_delay = 10
|
||||
ai_unbolt_delay = 5
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
dir = 1
|
||||
closed_layer = ABOVE_DOOR_LAYER
|
||||
explosion_resistance = 25
|
||||
destroy_hits = 40
|
||||
armor = list(
|
||||
MELEE = ARMOR_MELEE_MAJOR,
|
||||
BULLET = ARMOR_BALLISTIC_MEDIUM,
|
||||
LASER = ARMOR_LASER_RIFLE
|
||||
)
|
||||
pass_flags_self = PASSDOORS
|
||||
rad_resistance_modifier = 6
|
||||
|
||||
@@ -255,6 +261,12 @@
|
||||
icon_state = "shutter1"
|
||||
damage = SHUTTER_CRUSH_DAMAGE
|
||||
closed_layer = CLOSED_DOOR_LAYER
|
||||
destroy_hits = 20
|
||||
armor = list(
|
||||
MELEE = ARMOR_MELEE_RESISTANT,
|
||||
BULLET = ARMOR_BALLISTIC_PISTOL,
|
||||
LASER = ARMOR_LASER_MEDIUM
|
||||
)
|
||||
|
||||
/obj/structure/machinery/door/blast/shutters/open
|
||||
icon_state = "shutter0"
|
||||
|
||||
@@ -255,21 +255,25 @@
|
||||
var/damage = hitting_projectile.get_structure_damage()
|
||||
|
||||
// Emitter Blasts - these will eventually completely destroy the door, given enough time.
|
||||
if (damage > 90)
|
||||
destroy_hits -= (1 * hitting_projectile.anti_materiel_potential)
|
||||
if (damage >= 30 && health <= 0) //Midlaser damage.
|
||||
if (damage > 90)
|
||||
destroy_hits -= max(1, (1 * hitting_projectile.anti_materiel_potential)) //Double dip for strong projectiles, like emitters or the PEAC.
|
||||
destroy_hits -= max(1, (1 * hitting_projectile.anti_materiel_potential))
|
||||
if (destroy_hits <= 0)
|
||||
visible_message(SPAN_DANGER("\The [src.name] disintegrates!"))
|
||||
switch (hitting_projectile.damage_type)
|
||||
if(DAMAGE_BRUTE)
|
||||
new /obj/item/stack/material/steel(src.loc, 2)
|
||||
new /obj/item/stack/rods(src.loc, 3)
|
||||
for(var/i = 1 to 3)
|
||||
if(prob(50))
|
||||
new /obj/item/stack/material/steel(src.loc, 2)
|
||||
else
|
||||
new /obj/item/material/shard(src.loc, MATERIAL_STEEL)
|
||||
if(DAMAGE_BURN)
|
||||
new /obj/effect/decal/cleanable/ash(src.loc) // Turn it to ashes!
|
||||
new /obj/item/material/shard(src.loc, MATERIAL_STEEL)
|
||||
new /obj/particle_emitter/door_destruction(loc, 2 SECONDS)
|
||||
qdel(src)
|
||||
|
||||
if(damage)
|
||||
add_damage(damage)
|
||||
|
||||
/obj/structure/machinery/door/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
||||
..()
|
||||
var/tforce = 0
|
||||
@@ -419,6 +423,8 @@
|
||||
update_icon()
|
||||
|
||||
/obj/structure/machinery/door/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
set_broken()
|
||||
|
||||
/obj/structure/machinery/door/proc/set_broken()
|
||||
|
||||
@@ -1,506 +0,0 @@
|
||||
/obj/structure/machinery/mecha_part_fabricator
|
||||
name = "synthetic fabricator"
|
||||
desc = "A general purpose fabricator that can be used to fabricate equipment for synthetics or exosuits."
|
||||
icon = 'icons/obj/machinery/robotics_fabricator.dmi'
|
||||
icon_state = "fab"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 5000
|
||||
req_access = list(ACCESS_ROBOTICS)
|
||||
component_types = list(
|
||||
/obj/item/circuitboard/mechfab,
|
||||
/obj/item/stock_parts/matter_bin = 2,
|
||||
/obj/item/stock_parts/manipulator,
|
||||
/obj/item/stock_parts/micro_laser,
|
||||
/obj/item/stock_parts/console_screen
|
||||
)
|
||||
manufacturer = "hephaestus"
|
||||
|
||||
/**
|
||||
* A `/list` of enqueued `/datum/design` to be printed, processed in the queue
|
||||
*/
|
||||
var/list/datum/design/queue = list()
|
||||
|
||||
/**
|
||||
* How much efficient (or inefficient) the protolathe is at manufacturing things
|
||||
*/
|
||||
var/mat_efficiency = 1
|
||||
|
||||
/**
|
||||
* The production speed of this specific protolathe, a factor
|
||||
*/
|
||||
var/production_speed = 1
|
||||
|
||||
var/list/materials = list(MATERIAL_STEEL = 0, MATERIAL_GLASS = 0, MATERIAL_GOLD = 0, MATERIAL_SILVER = 0, MATERIAL_DIAMOND = 0, MATERIAL_PHORON = 0, MATERIAL_URANIUM = 0, MATERIAL_PLASTEEL = 0, MATERIAL_ALUMINIUM = 0, MATERIAL_LEAD = 0)
|
||||
var/res_max_amount = 200000
|
||||
|
||||
var/datum/research/files
|
||||
|
||||
/// The looping sound for production.
|
||||
var/datum/looping_sound/synth_fab/fab_loop
|
||||
|
||||
var/list/categories = list()
|
||||
var/category = null
|
||||
var/sync_message = ""
|
||||
var/limb_manufacturer
|
||||
|
||||
///The timer id for the build callback, if we're building something
|
||||
var/build_callback_timer
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/upgrade_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
. += "- Upgraded <b>matter bins</b> will increase material storage capacity."
|
||||
. += SPAN_NOTICE(" - The current storage capacity is <b>[res_max_amount / 2000]</b> sheets")
|
||||
. += "- Upgraded <b>micro-lasers</b> will increase fabrication speed."
|
||||
. += SPAN_NOTICE(" - The current speed increase is <b>[round((1 - (1 / production_speed)) * 100)]%</b>")
|
||||
. += "- Upgraded <b>manipulators</b> will improve material use efficiency."
|
||||
. += SPAN_NOTICE(" - The current cost reduction is <b>[round((1 - mat_efficiency) * 100)]%</b>")
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/antagonist_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
. += "Click-drag someone with long hair onto this machine to start feeding it their hair! This will hurt and piss them off!"
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/Initialize()
|
||||
. = ..()
|
||||
|
||||
files = new /datum/research(src) //Setup the research data holder.
|
||||
fab_loop = new(src)
|
||||
limb_manufacturer = GLOB.basic_robolimb.company
|
||||
update_categories()
|
||||
update_icon()
|
||||
|
||||
/// Make sure the machine starts the round properly synced.
|
||||
/obj/structure/machinery/mecha_part_fabricator/LateInitialize()
|
||||
. = ..()
|
||||
sync()
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/update_icon()
|
||||
ClearOverlays()
|
||||
update_fab_audio()
|
||||
if(panel_open)
|
||||
AddOverlays("[icon_state]_panel")
|
||||
if(!(stat & (NOPOWER|BROKEN)))
|
||||
AddOverlays(emissive_appearance(icon, "[icon_state]_lights"))
|
||||
AddOverlays("[icon_state]_lights")
|
||||
if(build_callback_timer)
|
||||
AddOverlays("[icon_state]_working")
|
||||
AddOverlays(emissive_appearance(icon, "[icon_state]_lights_working"))
|
||||
AddOverlays("[icon_state]_lights_working")
|
||||
|
||||
/// Starts and stops the necessary audio.
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/update_fab_audio()
|
||||
if(!fab_loop)
|
||||
return
|
||||
|
||||
if(build_callback_timer)
|
||||
fab_loop.start()
|
||||
else
|
||||
fab_loop.stop()
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/dismantle()
|
||||
SSmaterials.normalize_material_amounts(materials)
|
||||
for(var/f in materials.Copy())
|
||||
eject_materials(f, materials[f])
|
||||
|
||||
//Stop the queue building if you're dismantling
|
||||
deltimer(build_callback_timer)
|
||||
|
||||
..()
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/RefreshParts()
|
||||
..()
|
||||
res_max_amount = 0
|
||||
|
||||
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
|
||||
res_max_amount += M.rating * 100000 // 200k -> 600k
|
||||
var/T = 0
|
||||
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
T += M.rating
|
||||
mat_efficiency = 1 - (T - 1) / 4 // 1 -> 0.5
|
||||
|
||||
for(var/obj/item/stock_parts/micro_laser/M in component_parts) // Not resetting T is intended; speed is affected by both
|
||||
T += M.rating
|
||||
production_speed = T / 2 // 1 -> 3
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/attack_hand(var/mob/user)
|
||||
if(..())
|
||||
return
|
||||
if(!allowed(user))
|
||||
to_chat(user, SPAN_WARNING("Access denied."))
|
||||
return
|
||||
do_hair_pull(user)
|
||||
|
||||
// Yes I'm doing this after do_hair_pull() intentionally, you can totally fail the skill check and still get your hair stuck in a blender.
|
||||
var/cancelled = FALSE
|
||||
SEND_SIGNAL(user, COMSIG_USE_MECH_FAB, &cancelled)
|
||||
if (cancelled)
|
||||
return
|
||||
|
||||
ui_interact(user)
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/ui_interact(mob/user, datum/tgui/ui)
|
||||
. = ..()
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "SyntheticFabricator", "Synthetic Fabricator", 1200, 800)
|
||||
ui.open()
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["manufacturer"] = manufacturer
|
||||
var/datum/design/current = queue.len ? queue[1] : null
|
||||
if(current)
|
||||
data["current"] = current.name
|
||||
data["queue"] = get_queue_names()
|
||||
data["buildable"] = get_build_options()
|
||||
data["category"] = category
|
||||
data["available_categories"] = list()
|
||||
for(var/possible_category in categories)
|
||||
data["available_categories"] += list(list("name" = possible_category))
|
||||
|
||||
if(GLOB.fabricator_robolimbs)
|
||||
var/list/T = list()
|
||||
for(var/A in GLOB.fabricator_robolimbs)
|
||||
var/datum/robolimb/R = GLOB.fabricator_robolimbs[A]
|
||||
T += list(list("name" = R.company, "type" = A))
|
||||
data["manufacturers"] = T
|
||||
data["selected_manufacturer"] = limb_manufacturer
|
||||
|
||||
data["materials"] = get_materials()
|
||||
data["maximum_resource_amount"] = res_max_amount
|
||||
data["sync"] = sync_message
|
||||
|
||||
//If we have something in the queue that we're trying to build, show the time left if the build is undergoing, otherwise null
|
||||
//the logic of displaying it is handled client-side
|
||||
if(current)
|
||||
if(build_callback_timer)
|
||||
data["timeleft"] = round(timeleft(build_callback_timer))
|
||||
else
|
||||
data["timeleft"] = null
|
||||
return data
|
||||
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("build")
|
||||
var/path = text2path(params["build"])
|
||||
add_to_queue(path)
|
||||
. = TRUE
|
||||
|
||||
if("remove")
|
||||
remove_from_queue(text2num(params["remove"]))
|
||||
. = TRUE
|
||||
|
||||
if("category")
|
||||
if(params["category"] in categories)
|
||||
category = params["category"]
|
||||
. = TRUE
|
||||
|
||||
if("manufacturer")
|
||||
if(params["manufacturer"] in GLOB.fabricator_robolimbs)
|
||||
limb_manufacturer = params["manufacturer"]
|
||||
. = TRUE
|
||||
|
||||
if("eject")
|
||||
eject_materials(params["eject"], text2num(params["amount"]))
|
||||
. = TRUE
|
||||
|
||||
if("sync")
|
||||
sync()
|
||||
. = TRUE
|
||||
else
|
||||
sync_message = ""
|
||||
|
||||
if(.)
|
||||
playsound(src, 'sound/machines/synthfab/synthfab_button.ogg', 50)
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/attackby(obj/item/attacking_item, mob/user)
|
||||
if(build_callback_timer)
|
||||
to_chat(user, SPAN_NOTICE("\The [src] is busy. Please wait for completion of previous operation."))
|
||||
return TRUE
|
||||
if(default_deconstruction_screwdriver(user, attacking_item))
|
||||
return TRUE
|
||||
if(default_deconstruction_crowbar(user, attacking_item))
|
||||
return TRUE
|
||||
if(default_part_replacement(user, attacking_item))
|
||||
return TRUE
|
||||
|
||||
if(!istype(attacking_item, /obj/item/stack/material))
|
||||
return ..()
|
||||
|
||||
var/obj/item/stack/material/M = attacking_item
|
||||
if(!M.material)
|
||||
return ..()
|
||||
var/material = SSmaterials.material_to_path(M.material, FALSE)
|
||||
if(!(material in list(MATERIAL_STEEL, MATERIAL_GLASS, MATERIAL_GOLD, MATERIAL_SILVER, MATERIAL_DIAMOND, MATERIAL_PHORON, MATERIAL_URANIUM, MATERIAL_PLASTEEL, MATERIAL_ALUMINIUM, MATERIAL_LEAD)))
|
||||
to_chat(user, SPAN_WARNING("\The [src] cannot hold [M.material.name]."))
|
||||
return TRUE
|
||||
|
||||
var/sname = "[M.name]"
|
||||
SSmaterials.normalize_material_amounts(materials)
|
||||
if((materials[material] || 0) + SHEET_MATERIAL_AMOUNT <= res_max_amount)
|
||||
if(M.amount >= 1)
|
||||
var/count = 0
|
||||
var/mutable_appearance/MA = mutable_appearance(icon, "material_insertion")
|
||||
MA.color = M.material.icon_colour
|
||||
//first play the insertion animation
|
||||
flick_overlay_view(MA, 1 SECONDS)
|
||||
|
||||
//now play the progress bar animation
|
||||
flick_overlay_view(mutable_appearance(icon, "fab_progress"), 1 SECONDS)
|
||||
|
||||
while((materials[material] || 0) + SHEET_MATERIAL_AMOUNT <= res_max_amount && M.amount >= 1)
|
||||
SSmaterials.add_material_amount(materials, material, M.perunit)
|
||||
M.use(1)
|
||||
count++
|
||||
to_chat(user, SPAN_NOTICE("You insert [count] [sname] into \the [src]."))
|
||||
|
||||
//Wake up, we have things to do (maybe)
|
||||
handle_queue()
|
||||
|
||||
else
|
||||
to_chat(user, SPAN_NOTICE("\The [src] cannot hold more [sname]."))
|
||||
return TRUE
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/mouse_drop_receive(atom/dropped, mob/user, params)
|
||||
var/mob/living/carbon/human/target = dropped
|
||||
if (!istype(target) || target.buckled_to || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || istype(user, /mob/living/silicon/ai))
|
||||
return
|
||||
if(target == user)
|
||||
return
|
||||
src.add_fingerprint(user)
|
||||
var/target_loc = target.loc
|
||||
|
||||
if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis)
|
||||
if(isskrell(target) || isunathi(target))
|
||||
return
|
||||
|
||||
for(var/obj/item/protection in list(target.head))
|
||||
if(protection && (protection.flags_inv & BLOCKHAIR))
|
||||
return
|
||||
|
||||
var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_list[target.h_style]
|
||||
if(hair_style.length < 4)
|
||||
return
|
||||
|
||||
user.visible_message(SPAN_WARNING("[user] starts feeding [target]'s hair into \the [src]!"), SPAN_WARNING("You start feeding [target]'s hair into \the [src]!"))
|
||||
if(!do_after(user, 5 SECONDS, target, DO_UNIQUE))
|
||||
return
|
||||
if(target_loc != target.loc)
|
||||
return
|
||||
if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis)
|
||||
user.visible_message(SPAN_WARNING("[user] feeds the [target]'s hair into the [src] and flicks it on!"), SPAN_ALERT("You turn the [src] on!"))
|
||||
do_hair_pull(target)
|
||||
user.attack_log += "\[[time_stamp()]\] <span class='warning'>Has fed [target.name]'s ([target.ckey]) hair into a [src].</span>"
|
||||
target.attack_log += "\[[time_stamp()]\] <font color='orange'>Has had their hair fed into [src] by [user.name] ([user.ckey])</font>"
|
||||
msg_admin_attack("[key_name_admin(user)] fed [key_name_admin(target)] in a [src]. (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",ckey=key_name(user),ckey_target=key_name(target))
|
||||
else
|
||||
return
|
||||
if(!do_after(user, 3.5 SECONDS, target, DO_UNIQUE))
|
||||
return
|
||||
if(target_loc != target.loc)
|
||||
return
|
||||
if(target != user && !user.restrained() && !user.stat && !user.weakened && !user.stunned && !user.paralysis)
|
||||
user.visible_message(SPAN_ALERT("[user] starts tugging on [target]'s head as the [src] keeps running!"), SPAN_ALERT("You start tugging on [target]'s head!"))
|
||||
do_hair_pull(target)
|
||||
spawn(10)
|
||||
user.visible_message(SPAN_ALERT("[user] stops the [src] and leaves [target] resting as they are."), SPAN_ALERT("You turn the [src] off and let go of [target]."))
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/emag_act(var/remaining_charges, var/mob/user)
|
||||
switch(emagged)
|
||||
if(0)
|
||||
emagged = 0.5
|
||||
visible_message("[icon2html(src, viewers(get_turf(src)))] <b>[src]</b> beeps: \"DB error \[Code 0x00F1\]\"")
|
||||
sleep(10)
|
||||
visible_message("[icon2html(src, viewers(get_turf(src)))] <b>[src]</b> beeps: \"Attempting auto-repair\"")
|
||||
sleep(15)
|
||||
visible_message("[icon2html(src, viewers(get_turf(src)))] <b>[src]</b> beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"")
|
||||
sleep(30)
|
||||
visible_message("[icon2html(src, viewers(get_turf(src)))] <b>[src]</b> beeps: \"User DB truncated. Please contact your [SSatlas.current_map.company_name] system operator for future assistance.\"")
|
||||
req_access = null
|
||||
emagged = 1
|
||||
return 1
|
||||
if(0.5)
|
||||
visible_message("[icon2html(src, viewers(get_turf(src)))] <b>[src]</b> beeps: \"DB not responding \[Code 0x0003\]...\"")
|
||||
if(1)
|
||||
visible_message("[icon2html(src, viewers(get_turf(src)))] <b>[src]</b> beeps: \"No records in User DB\"")
|
||||
|
||||
/**
|
||||
* Adds a design to the queue
|
||||
*
|
||||
* * path: The path of the design to add
|
||||
*/
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/add_to_queue(path)
|
||||
var/datum/design/D = files.known_designs[path]
|
||||
if(!D)
|
||||
return
|
||||
queue += D
|
||||
|
||||
//Wake up, we have things to do
|
||||
handle_queue()
|
||||
|
||||
/**
|
||||
* Removes a design from the queue
|
||||
*
|
||||
* * index: The index of the design to remove
|
||||
*/
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/remove_from_queue(index)
|
||||
queue.Cut(index, index + 1)
|
||||
|
||||
//If we're removing the first thing in the queue, stop the build timer
|
||||
if(index == 1)
|
||||
deltimer(build_callback_timer)
|
||||
build_callback_timer = null
|
||||
|
||||
//Wake up, we have things to do
|
||||
handle_queue()
|
||||
|
||||
/**
|
||||
* Handle the construction queue
|
||||
*/
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/handle_queue()
|
||||
|
||||
//No work to do or already busy, stop
|
||||
if(!length(queue) || build_callback_timer)
|
||||
//If we don't have a build in progress, revert to idle power usage
|
||||
if(!build_callback_timer)
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
|
||||
update_icon()
|
||||
return
|
||||
|
||||
//If there's no power, there's no building
|
||||
if(stat & NOPOWER)
|
||||
queue = list()
|
||||
return
|
||||
|
||||
//Get the first design in the queue
|
||||
var/datum/design/D = queue[1]
|
||||
|
||||
//If we can build it, process the request
|
||||
if(can_build(D))
|
||||
update_use_power(POWER_USE_ACTIVE)
|
||||
|
||||
//Add the callback timer for printing, and remove the design from the queue
|
||||
build_callback_timer = addtimer(CALLBACK(src, PROC_REF(build), D), (D.time / production_speed), TIMER_UNIQUE|TIMER_STOPPABLE)
|
||||
//No queue removal here because we show how long it takes to build in the UI
|
||||
|
||||
else
|
||||
visible_message(SPAN_NOTICE("[icon2html(src, viewers(get_turf(src)))] \The [src] flashes: Insufficient materials to complete build: [D.name]."))
|
||||
remove_from_queue(1)
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/can_build(var/datum/design/D)
|
||||
SSmaterials.normalize_material_amounts(materials)
|
||||
for(var/M in D.materials)
|
||||
var/material = SSmaterials.material_to_path(M, FALSE)
|
||||
if(!material)
|
||||
material = M
|
||||
if((materials[material] || 0) < D.materials[M] * mat_efficiency)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/**
|
||||
* Builds the given design, assuming all the necessary conditions are met
|
||||
*
|
||||
* * design_to_build: The design to build
|
||||
*/
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/build(datum/design/design_to_build)
|
||||
//Consume the materials
|
||||
SSmaterials.normalize_material_amounts(materials)
|
||||
for(var/M in design_to_build.materials)
|
||||
SSmaterials.remove_material_amount(materials, M, design_to_build.materials[M] * mat_efficiency)
|
||||
|
||||
intent_message(MACHINE_SOUND)
|
||||
|
||||
if(design_to_build.build_path)
|
||||
var/loc_offset = get_step(src, dir)
|
||||
var/obj/new_item = design_to_build.Fabricate(loc_offset, src)
|
||||
visible_message("\The <b>[src]</b> pings, indicating that \the [new_item] is complete.", "You hear a ping.", intent_message = PING_SOUND)
|
||||
if(mat_efficiency != 1)
|
||||
if(new_item.matter && new_item.matter.len > 0)
|
||||
for(var/i in new_item.matter)
|
||||
new_item.matter[i] = new_item.matter[i] * mat_efficiency
|
||||
|
||||
//We finished building, clear the timer and remove the thing from the queue
|
||||
build_callback_timer = null
|
||||
remove_from_queue(1)
|
||||
|
||||
//Do the queue handling for the next item, or to stop
|
||||
handle_queue()
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/get_queue_names()
|
||||
. = list()
|
||||
for(var/i = 1 to queue.len)
|
||||
var/datum/design/D = queue[i]
|
||||
. += list(list("name" = D.name, "time" = get_design_time(D), "index" = i))
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/get_build_options()
|
||||
. = list()
|
||||
for(var/path in files.known_designs)
|
||||
var/datum/design/D = files.known_designs[path]
|
||||
if(!D.build_path || !(D.build_type & MECHFAB) || !D.category || (D.category != category))
|
||||
continue
|
||||
. += list(list("name" = D.name, "desc" = D.desc, "type" = D.type, "category" = D.category, "resources" = get_design_resourses(D), "time" = get_design_time(D)))
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/get_design_resourses(var/datum/design/D)
|
||||
var/list/F = list()
|
||||
for(var/T in D.materials)
|
||||
F += "[SSmaterials.material_display_name(T)]: [D.materials[T] * mat_efficiency]"
|
||||
return english_list(F, and_text = ", ")
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/get_design_time(var/datum/design/D)
|
||||
return time2text(round(10 * D.time / production_speed), "mm:ss")
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/update_categories()
|
||||
categories = list()
|
||||
for(var/path in files.known_designs)
|
||||
var/datum/design/D = files.known_designs[path]
|
||||
if(!D.build_path || !(D.build_type & MECHFAB) || !D.category)
|
||||
continue
|
||||
categories |= D.category
|
||||
if(!category || !(category in categories))
|
||||
category = categories[1]
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/get_materials()
|
||||
. = list()
|
||||
SSmaterials.normalize_material_amounts(materials)
|
||||
for(var/T in materials)
|
||||
. += list(list("name" = SSmaterials.material_display_name(T), "amount" = materials[T]))
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/eject_materials(var/material, var/amount)
|
||||
if(!amount)
|
||||
return
|
||||
SSmaterials.normalize_material_amounts(materials)
|
||||
material = SSmaterials.material_to_path(material, FALSE)
|
||||
if(!material)
|
||||
return
|
||||
var/stack_type = SSmaterials.material_stack_type(material)
|
||||
if(!stack_type)
|
||||
return
|
||||
|
||||
var/real_amount = min(round(amount / SHEET_MATERIAL_AMOUNT), round((materials[material] || 0) / SHEET_MATERIAL_AMOUNT))
|
||||
if(real_amount < 1)
|
||||
return
|
||||
var/obj/item/stack/material/S = new stack_type(loc, real_amount)
|
||||
S.update_icon()
|
||||
SSmaterials.remove_material_amount(materials, material, real_amount * SHEET_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/structure/machinery/mecha_part_fabricator/proc/sync()
|
||||
sync_message = "Error: no console found."
|
||||
for(var/obj/structure/machinery/computer/rdconsole/RDC in get_area(src))
|
||||
if(!RDC.sync)
|
||||
continue
|
||||
for(var/id in RDC.files.known_tech)
|
||||
var/datum/tech/T = RDC.files.known_tech[id]
|
||||
files.AddTech2Known(T)
|
||||
files.RefreshResearch()
|
||||
sync_message = "Sync complete."
|
||||
update_categories()
|
||||
@@ -1,4 +1,7 @@
|
||||
GLOBAL_VAR(bomb_set)
|
||||
// Security needs time to respond to it
|
||||
#define MIN_BOMB_TIMER 600
|
||||
#define MAX_BOMB_TIMER 900
|
||||
|
||||
/obj/structure/machinery/nuclearbomb
|
||||
name = "\improper Nuclear Fission Explosive"
|
||||
@@ -11,7 +14,7 @@ GLOBAL_VAR(bomb_set)
|
||||
var/deployable = 0
|
||||
var/extended = 0
|
||||
var/lighthack = 0
|
||||
var/timeleft = 120
|
||||
var/timeleft = MIN_BOMB_TIMER
|
||||
var/timing = 0
|
||||
var/alerted = 0
|
||||
var/r_code = "ADMIN"
|
||||
@@ -268,7 +271,7 @@ GLOBAL_VAR(bomb_set)
|
||||
switch(action)
|
||||
if("time")
|
||||
timeleft += text2num(params["value"])
|
||||
timeleft = clamp(timeleft, 120, 600)
|
||||
timeleft = clamp(timeleft, MIN_BOMB_TIMER, MAX_BOMB_TIMER)
|
||||
return TRUE
|
||||
if("timer")
|
||||
if(timing == -1)
|
||||
@@ -282,6 +285,9 @@ GLOBAL_VAR(bomb_set)
|
||||
if(wires.is_cut(WIRE_TIMING))
|
||||
to_chat(usr, SPAN_WARNING("Nothing happens, something might be wrong with the wiring."))
|
||||
return TRUE
|
||||
if(!area_safety_check())
|
||||
audible_message(SPAN_WARNING("\The [src] emits a beep, \"Deployment aborted: local radiation shielding prevents reliable detonation coupling.\""), "\The [src]'s deployment light blinks red once and disables.")
|
||||
return TRUE
|
||||
if(!timing && !safety)
|
||||
timing = 1
|
||||
log_and_message_admins("engaged a nuclear bomb")
|
||||
@@ -290,7 +296,7 @@ GLOBAL_VAR(bomb_set)
|
||||
else
|
||||
secure_device()
|
||||
if(alerted == 0)
|
||||
set_security_level(SEC_LEVEL_DELTA)
|
||||
set_security_level(SEC_LEVEL_DELTA, TRUE, get_area(src))
|
||||
alerted = 1
|
||||
return TRUE
|
||||
if("safety")
|
||||
@@ -307,7 +313,13 @@ GLOBAL_VAR(bomb_set)
|
||||
anchored = 0
|
||||
visible_message(SPAN_WARNING("\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut."))
|
||||
return TRUE
|
||||
if(!isinspace())
|
||||
if(isinspace())
|
||||
to_chat(usr, SPAN_WARNING("There is nothing to anchor to!"))
|
||||
return TRUE
|
||||
if(!area_safety_check())
|
||||
audible_message(SPAN_WARNING("\The [src] emits a beep, \"Deployment aborted: local radiation shielding prevents reliable detonation coupling.\""), "\The [src]'s deployment light blinks red once and disables.")
|
||||
return TRUE
|
||||
else
|
||||
anchored = !anchored
|
||||
if(anchored)
|
||||
visible_message(SPAN_WARNING("With a steely snap, bolts slide out of [src] and anchor it to the flooring."))
|
||||
@@ -316,8 +328,6 @@ GLOBAL_VAR(bomb_set)
|
||||
secure_device()
|
||||
visible_message(SPAN_WARNING("The anchoring bolts slide back into the depths of [src]."))
|
||||
playsound(src, 'sound/machines/boltsup.ogg', 30, 0, extrarange = SILENCED_SOUND_EXTRARANGE)
|
||||
else
|
||||
to_chat(usr, SPAN_WARNING("There is nothing to anchor to!"))
|
||||
return TRUE
|
||||
|
||||
/obj/structure/machinery/nuclearbomb/proc/secure_device()
|
||||
@@ -326,12 +336,22 @@ GLOBAL_VAR(bomb_set)
|
||||
|
||||
GLOB.bomb_set--
|
||||
timing = 0
|
||||
timeleft = clamp(timeleft, 120, 600)
|
||||
timeleft = clamp(timeleft, MIN_BOMB_TIMER, MAX_BOMB_TIMER)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/machinery/nuclearbomb/ex_act(severity)
|
||||
return
|
||||
|
||||
// Is it in a valid area
|
||||
/obj/structure/machinery/nuclearbomb/proc/area_safety_check()
|
||||
var/area/A = get_area(src)
|
||||
// It needs to be the game map and not in a rad shielded area.
|
||||
// That keeps it out of maintenance and other areas we don't want it deployed in
|
||||
if(A.area_flags & AREA_FLAG_RAD_SHIELDED || !A.station_area)
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
#define NUKERANGE 80
|
||||
/obj/structure/machinery/nuclearbomb/proc/explode()
|
||||
if (src.safety)
|
||||
@@ -347,10 +367,9 @@ GLOBAL_VAR(bomb_set)
|
||||
sleep(100)
|
||||
|
||||
var/off_station = 0
|
||||
var/turf/bomb_location = get_turf(src)
|
||||
if(bomb_location && is_station_level(bomb_location.z))
|
||||
if( (bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)) )
|
||||
off_station = 1
|
||||
// This should really not be necessary, but lets do it just to be safe.
|
||||
if(!area_safety_check() && isinspace())
|
||||
off_station = 1
|
||||
else
|
||||
off_station = 2
|
||||
|
||||
@@ -365,7 +384,7 @@ GLOBAL_VAR(bomb_set)
|
||||
if(SSticker.mode)
|
||||
SSticker.mode.explosion_in_progress = 0
|
||||
if(off_station == 1)
|
||||
to_world("<b>A nuclear device was set off, but the explosion was out of reach of the [station_name(TRUE)]!</b>")
|
||||
to_world("<b>A nuclear device was set off, but the explosion was unable to destroy the [station_name(TRUE)]!</b>")
|
||||
else if(off_station == 2)
|
||||
to_world("<b>A nuclear device was set off, but the device was not on the [station_name(TRUE)]!</b>")
|
||||
else
|
||||
@@ -469,3 +488,6 @@ GLOBAL_VAR(bomb_set)
|
||||
continue
|
||||
T.icon_state = target_icon_state
|
||||
last_turf_state = target_icon_state
|
||||
|
||||
#undef MIN_BOMB_TIMER
|
||||
#undef MAX_BOMB_TIMER
|
||||
|
||||
@@ -500,8 +500,6 @@
|
||||
if(. != BULLET_ACT_HIT)
|
||||
return .
|
||||
|
||||
add_damage(damage)
|
||||
|
||||
/obj/structure/machinery/porta_turret/emp_act(severity)
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
/obj/item/clothing/mask/smokable/ecig,
|
||||
/obj/item/inductive_charger/handheld,
|
||||
/obj/item/auto_cpr,
|
||||
/obj/item/personal_shield
|
||||
/obj/item/personal_shield,
|
||||
/obj/item/electronic_assembly
|
||||
)
|
||||
var/icon_state_charged = "recharger100"
|
||||
var/icon_state_charging = "recharger"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
var/icon_update_tick = 0 // Used to rebuild the overlay only once every 10 ticks
|
||||
|
||||
///Multiplier applied to all operations of giving power to cells, represents entropy, efficiency increases with upgrades
|
||||
var/charging_efficiency = 1.3
|
||||
var/charging_efficiency = 2
|
||||
|
||||
///Watts, Power rating drawn from internal cell to recharge occupant's cell 60 kW unupgraded
|
||||
var/charging_power
|
||||
@@ -229,7 +229,7 @@
|
||||
man_rating += P.rating
|
||||
cell = locate(/obj/item/cell) in component_parts
|
||||
|
||||
charging_efficiency = 1.3 + 0.030 * cap_rating
|
||||
charging_efficiency = 2 + 0.030 * cap_rating
|
||||
charging_power = 30000 + 12000 * cap_rating
|
||||
restore_power_active = 10000 + 10000 * cap_rating
|
||||
restore_power_passive = 5000 + 1000 * cap_rating
|
||||
|
||||
@@ -69,7 +69,10 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/machinery/stasis_cage/process(seconds_per_tick)
|
||||
if (use_power || !cell || !cell.charge)
|
||||
if (!use_power || !cell || !cell.charge)
|
||||
if (isanimal(contained))
|
||||
var/mob/living/simple_animal/SA = contained
|
||||
SA.in_stasis = FALSE
|
||||
return
|
||||
cell.use(2 * seconds_per_tick)
|
||||
if (contained)
|
||||
@@ -100,7 +103,10 @@
|
||||
release()
|
||||
|
||||
/obj/structure/machinery/stasis_cage/proc/release()
|
||||
if (contained)
|
||||
if(contained)
|
||||
if(isanimal(contained))
|
||||
var/mob/living/simple_animal/SA = contained
|
||||
SA.in_stasis = FALSE
|
||||
contained.dropInto(src)
|
||||
contained = null
|
||||
playsound(get_turf(src), 'sound/machines/airlock.ogg', 40)
|
||||
@@ -249,6 +255,12 @@
|
||||
playsound(src, 'sound/machines/AirlockClose.ogg', 100)
|
||||
add_fingerprint(user)
|
||||
if (do_after(user, 2 SECONDS, src))
|
||||
if(QDELETED(target) || contained || broken || !use_power)
|
||||
return
|
||||
if(target.buckled_to)
|
||||
target.buckled_to.unbuckle()
|
||||
if(istype(target.buckled_to, /obj/item/trap/animal))
|
||||
var/obj/item/trap/animal/animal_trap = target.buckled_to
|
||||
animal_trap.release(transferring = TRUE)
|
||||
else
|
||||
target.buckled_to.unbuckle()
|
||||
contain(user, target)
|
||||
|
||||
@@ -178,6 +178,11 @@
|
||||
|
||||
var/list/receive = get_hearers_in_radio_ranges(radios)
|
||||
|
||||
// Electronic radio headsets expose received traffic to their built-in
|
||||
// command receiver independently of whether a mob can hear the message.
|
||||
for(var/obj/item/radio/headset/circuitry/circuit_headset in radios)
|
||||
circuit_headset.receive_circuit_radio_command(data["name"], message, get_frequency_name(frequency))
|
||||
|
||||
// Cut out admins which have radio chatter disabled
|
||||
for (var/mob/R in receive)
|
||||
if(R.client && R.client.holder && !(R.client.prefs.toggles & CHAT_RADIO))
|
||||
|
||||
@@ -19,15 +19,18 @@
|
||||
vend_id = "robo-tools"
|
||||
products = list(
|
||||
/obj/item/stack/cable_coil = 4,
|
||||
/obj/item/flash/synthetic = 4,
|
||||
/obj/item/flash/synthetic = 10,
|
||||
/obj/item/cell/high = 12,
|
||||
/obj/item/assembly/prox_sensor = 8,
|
||||
/obj/item/assembly/signaler = 20,
|
||||
/obj/item/healthanalyzer = 3,
|
||||
/obj/item/surgery/scalpel = 2,
|
||||
/obj/item/surgery/hemostat = 2,
|
||||
/obj/item/storage/firstaid/empty = 2,
|
||||
/obj/item/surgery/circular_saw = 2,
|
||||
/obj/item/screwdriver = 5,
|
||||
/obj/item/crowbar = 5
|
||||
/obj/item/crowbar = 5,
|
||||
/obj/item/mmi = 2
|
||||
)
|
||||
contraband = list(
|
||||
/obj/item/flash = 2
|
||||
|
||||
@@ -506,6 +506,14 @@
|
||||
/obj/item/clothing/suit/storage/tajaran/messa = 3,
|
||||
/obj/item/clothing/suit/storage/tajaran/matake = 2,
|
||||
/obj/item/clothing/suit/storage/tajaran/azubarre = 2,
|
||||
/obj/item/clothing/suit/storage/hooded/trinary_robes = 1,
|
||||
/obj/item/clothing/suit/storage/hooded/trinary_robes/templeist = 1,
|
||||
/obj/item/clothing/suit/storage/hooded/trinary_robes/habit = 1,
|
||||
/obj/item/clothing/head/trinary = 1,
|
||||
/obj/item/clothing/accessory/poncho/trinary/shouldercape = 1,
|
||||
/obj/item/clothing/accessory/poncho/trinary/pellegrina = 1,
|
||||
/obj/item/clothing/accessory/poncho/trinary = 1,
|
||||
/obj/item/clothing/accessory/badge/trinary = 1,
|
||||
/obj/item/clothing/head/chaplain_hood = 3,
|
||||
/obj/item/clothing/head/nun_hood = 3,
|
||||
/obj/item/clothing/head/hijab = 3,
|
||||
@@ -515,6 +523,7 @@
|
||||
/obj/item/clothing/mask/trinary_mask = 3,
|
||||
/obj/item/clothing/mask/gas/unathi = 3,
|
||||
/obj/item/clothing/mask/tajara = 3,
|
||||
/obj/item/clothing/ears/antenna/trinary_halo = 1,
|
||||
/obj/item/clothing/accessory/apron/dharmela = 2,
|
||||
/obj/item/clothing/shoes/sneakers/black = 3,
|
||||
/obj/item/storage/box/fancy/candle_box = 3,
|
||||
|
||||
@@ -202,7 +202,6 @@
|
||||
if(. != BULLET_ACT_HIT)
|
||||
return .
|
||||
|
||||
health -= hitting_projectile.damage
|
||||
bullet_ping(hitting_projectile)
|
||||
CheckHealth()
|
||||
|
||||
|
||||
@@ -114,8 +114,6 @@
|
||||
if(. != BULLET_ACT_HIT)
|
||||
return .
|
||||
|
||||
add_damage(proj_damage, hitting_projectile.damage_flags(), hitting_projectile.damage_type, hitting_projectile.armor_penetration, hitting_projectile)
|
||||
|
||||
/obj/structure/window/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1)
|
||||
|
||||
Reference in New Issue
Block a user