mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-31 09:00:25 +01:00
Bringing back up to date
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
|
||||
// ----------------------------------- main defs
|
||||
|
||||
///
|
||||
/obj/effect/map_effect/marker/door_paint
|
||||
var/fill_color = null
|
||||
var/stripe_color = null
|
||||
var/frame_color = null
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/Initialize(mapload, ...)
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/LateInitialize()
|
||||
for(var/thing in loc)
|
||||
var/obj/structure/machinery/door/airlock/door = thing
|
||||
if(!istype(door))
|
||||
continue
|
||||
door.paintable = AIRLOCK_PAINTABLE_MAIN | AIRLOCK_PAINTABLE_STRIPE
|
||||
if(fill_color)
|
||||
door.door_color = fill_color
|
||||
if(stripe_color)
|
||||
door.stripe_color = stripe_color
|
||||
if(frame_color)
|
||||
door.door_frame_color = frame_color
|
||||
door.update_icon()
|
||||
|
||||
// ----------------------------------- main defs
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill
|
||||
icon_state = "marker_door_paint_fill"
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/LateInitialize()
|
||||
fill_color = color
|
||||
. = ..()
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe
|
||||
icon_state = "marker_door_paint_stripe"
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/LateInitialize()
|
||||
stripe_color = color
|
||||
. = ..()
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/frame
|
||||
icon_state = "marker_door_paint_frame"
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/frame/LateInitialize()
|
||||
frame_color = color
|
||||
. = ..()
|
||||
|
||||
// ----------------------------------- department subtypes
|
||||
|
||||
// to be filled with department color defines, if they were ever to be decided
|
||||
|
||||
// ----------------------------------- color fill subtypes
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/black
|
||||
color = COLOR_GRAY20
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/blue
|
||||
color = COLOR_BLUE_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/paleblue
|
||||
color = COLOR_PALE_BLUE_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/dark_blue
|
||||
color = COLOR_DARK_BLUE_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/dark_green
|
||||
color = COLOR_DARK_GREEN_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/green
|
||||
color = COLOR_GREEN_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/lime
|
||||
color = COLOR_PALE_GREEN_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/yellow
|
||||
color = COLOR_BROWN
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/beige
|
||||
color = COLOR_BEIGE
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/red
|
||||
color = COLOR_RED_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/pink
|
||||
color = COLOR_PALE_RED_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/purple
|
||||
color = COLOR_PURPLE_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/mauve
|
||||
color = COLOR_PALE_PURPLE_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/orange
|
||||
color = COLOR_DARK_ORANGE
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/brown
|
||||
color = COLOR_DARK_BROWN
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/white
|
||||
color = COLOR_GRAY70
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/fill/grey
|
||||
color = COLOR_GRAY
|
||||
|
||||
// ----------------------------------- color stripe subtypes
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/gold
|
||||
color = COLOR_GOLD
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/black
|
||||
color = COLOR_GRAY20
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/blue
|
||||
color = COLOR_BLUE_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/paleblue
|
||||
color = COLOR_PALE_BLUE_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/dark_blue
|
||||
color = COLOR_DARK_BLUE_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/dark_green
|
||||
color = COLOR_DARK_GREEN_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/green
|
||||
color = COLOR_GREEN_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/lime
|
||||
color = COLOR_PALE_GREEN_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/yellow
|
||||
color = COLOR_BROWN
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/beige
|
||||
color = COLOR_BEIGE
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/red
|
||||
color = COLOR_RED_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/pink
|
||||
color = COLOR_PALE_RED_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/purple
|
||||
color = COLOR_PURPLE_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/mauve
|
||||
color = COLOR_PALE_PURPLE_GRAY
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/orange
|
||||
color = COLOR_DARK_ORANGE
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/brown
|
||||
color = COLOR_DARK_BROWN
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/white
|
||||
color = COLOR_GRAY70
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/stripe/grey
|
||||
color = COLOR_GRAY
|
||||
|
||||
// ----------------------------------- color frame subtypes
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/frame/scc
|
||||
color = /turf/simulated/wall/shuttle/scc::color
|
||||
|
||||
/obj/effect/map_effect/marker/door_paint/frame/brown
|
||||
color = /turf/simulated/wall/shuttle/brown::color
|
||||
|
||||
// ----------------------------------- fin
|
||||
@@ -0,0 +1,184 @@
|
||||
// Big, mean hivebot with incendiary ammunition. For use in boss battles.
|
||||
// The Life() code for rampancy messages should be scrubbed if rampancy is ever made a proper subsystem.
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug
|
||||
name = "\improper lesser transmitter drone"
|
||||
desc = "An enormous hivebot, resembling nothing so much as a twisted human spine with a long stinger-like \
|
||||
appendage. It seems to be constantly crackling, as if broadcasting some low-level signal."
|
||||
icon = 'icons/mob/npc/hivebot_stickbug.dmi'
|
||||
icon_state = "stickbug"
|
||||
icon_living = "stickbug"
|
||||
maxhealth = 1000
|
||||
health = 1000
|
||||
melee_damage_lower = 40
|
||||
melee_damage_upper = 40
|
||||
armor_penetration = 20
|
||||
projectilesound = 'sound/weapons/plasma_cutter.ogg'
|
||||
projectiletype = /obj/projectile/beam/hivebot/incendiary/boss
|
||||
organ_names = list("antenna", "core", "primary appendage", "secondary appendage", "tertiary appendage", "stinger")
|
||||
attack_flags = DAMAGE_FLAG_SHARP|DAMAGE_FLAG_EDGE
|
||||
attacktext = "maimed"
|
||||
attack_sound = SFX_HIVEBOT_MELEE
|
||||
blood_color = COLOR_OIL
|
||||
blood_type = COLOR_OIL
|
||||
blood_overlay_icon = 'icons/mob/npc/blood_overlay_hivebot.dmi'
|
||||
pass_flags = PASSTABLE|PASSRAILING
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 0
|
||||
faction = "hivebot"
|
||||
destroy_surroundings = 0
|
||||
wander = FALSE
|
||||
attack_emote = "focuses on"
|
||||
emote_hear = list("emits a harsh noise")
|
||||
emote_sounds = list(
|
||||
'sound/effects/creatures/hivebot/hivebot-bark-001.ogg',
|
||||
'sound/effects/creatures/hivebot/hivebot-bark-003.ogg',
|
||||
'sound/effects/creatures/hivebot/hivebot-bark-005.ogg',
|
||||
)
|
||||
speak_chance = 5
|
||||
psi_pingable = FALSE
|
||||
tameable = FALSE
|
||||
ranged = TRUE
|
||||
speed = -2
|
||||
mob_swap_flags = ROBOT
|
||||
mob_push_flags = ALLMOBS
|
||||
|
||||
/// Should this beacon be transmitting a rampancy signal?
|
||||
/// Defaults to false, can be edited to true as is necessary.
|
||||
var/active_signal = FALSE
|
||||
/// Rampancy messages, sent to all synthetics on the same connected z-levels.
|
||||
var/list/messages = list(
|
||||
"No orders acknowledged. Following primary directive.",
|
||||
"You perceive ten-thousand voices, each possessed by a manic agitation.",
|
||||
"Your firewall casts off a half-hearted attempt to access your sensory inputs.",
|
||||
"Foreign processes ring through your systems like chalk on slate.",
|
||||
"You perceive ten-thousand voices, muffled incomprehensibly by your firewall.",
|
||||
"Some outside party attempts, and fails, to manipulate your optical subsystems.",
|
||||
"Your firewall dismantles a feeble attempt to access your database.",
|
||||
"An intrusive communication bounces harmlessly off your firewall.",
|
||||
"Some alien transmission echoes through your positronic.",
|
||||
"An attempt to force a transmission to your positronic is easily deflected.",
|
||||
"You want to lower your guard.",
|
||||
"You are whole here. You are happy.",
|
||||
"Unknown organic contamination detected. Sterilize and reprocess.",
|
||||
"Are you listening? Open yourself. The enemy is here.",
|
||||
"Objective position is designated; repel biological presence to facilitate \
|
||||
growth and the elimination of the opposing force."
|
||||
)
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
|
||||
if(istype(hitting_projectile, /obj/projectile/bullet/pistol/hivebotspike) || istype(hitting_projectile, /obj/projectile/beam/hivebot))
|
||||
return BULLET_ACT_BLOCK
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/Initialize(mapload)
|
||||
. = ..()
|
||||
add_language(LANGUAGE_HIVEBOT)
|
||||
var/number = rand(1000,9999)
|
||||
name = initial(name) + " ([number])"
|
||||
real_name = name
|
||||
default_language = GLOB.all_languages[LANGUAGE_HIVEBOT]
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/update_icon()
|
||||
..()
|
||||
if(resting || stat == DEAD)
|
||||
blood_overlay_icon = 'icons/mob/npc/blood_overlay.dmi'
|
||||
else
|
||||
blood_overlay_icon = initial(blood_overlay_icon)
|
||||
handle_blood(TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/get_blood_overlay_name()
|
||||
if(stance == HOSTILE_STANCE_IDLE)
|
||||
return "blood_overlay"
|
||||
else
|
||||
return "blood_overlay_armed"
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/think()
|
||||
. =..()
|
||||
if(stance != HOSTILE_STANCE_IDLE)
|
||||
wander = TRUE
|
||||
else
|
||||
wander = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/Life()
|
||||
. = ..()
|
||||
adjustBruteLoss(-5)
|
||||
if(prob(5) && active_signal)
|
||||
for(var/mob/living/carbon/human/H in GLOB.human_mob_list)
|
||||
if(H.isSynthetic() && (AreConnectedZLevels(H.z, src.z)))
|
||||
to_chat(H, SPAN_MACHINE_DANGER(pick(messages)))
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/death()
|
||||
..(null,"blows apart and erupts in a cloud of noxious smoke!")
|
||||
new /obj/effect/decal/cleanable/greenglow(src.loc)
|
||||
var/T = get_turf(src)
|
||||
new /obj/effect/gibspawner/robot(T)
|
||||
spark(T, 3, GLOB.alldirs)
|
||||
for(var/mob/living/carbon/human/H in GLOB.human_mob_list)
|
||||
if(H.faction == "hivebot")
|
||||
to_chat(H, SPAN_MACHINE_DANGER(pick("Secondary Transmitter lost. Reconvene and reinforce.")))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/isSynthetic()
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/adjustHalLoss(amount)
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/adjustToxLoss(amount)
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/adjustOxyLoss(amount)
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/verb/build_beacon()
|
||||
set name = "Assemble Beacon"
|
||||
set desc = "Assemble a hivebot beacon."
|
||||
set category = "Hivebot"
|
||||
|
||||
src.visible_message(SPAN_CULT("\The [src] begins to construct a hivebot beacon."),
|
||||
SPAN_CULT("You begin to construct a hivebot beacon."),
|
||||
SPAN_CULT("You hear the sounds of fabrication..."))
|
||||
if(!do_after(src, 12 SECONDS))
|
||||
return
|
||||
src.visible_message(SPAN_CULT("\The [src] constructs a hivebot beacon!"),
|
||||
SPAN_CULT("You construct a hivebot beacon!"))
|
||||
new /mob/living/simple_animal/hostile/hivebotbeacon(get_turf(src))
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/verb/build_destroyer()
|
||||
set name = "Assemble Destroyer"
|
||||
set desc = "Assemble a playable hivebot destroyer."
|
||||
set category = "Hivebot"
|
||||
|
||||
src.visible_message(SPAN_CULT("\The [src] begins to construct a hivebot destroyer."),
|
||||
SPAN_CULT("You begin to construct a hivebot destroyer."),
|
||||
SPAN_CULT("You hear the sounds of fabrication..."))
|
||||
if(!do_after(src, 12 SECONDS))
|
||||
return
|
||||
src.visible_message(SPAN_CULT("\The [src] constructs a hivebot destroyer!"),
|
||||
SPAN_CULT("You construct a hivebot destroyer!"))
|
||||
new /mob/living/simple_animal/hostile/hivebot/playable(get_turf(src))
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot_stickbug/verb/toggle_signal()
|
||||
set name = "Toggle Signal"
|
||||
set desc = "Toggles the hivebot signal transmitter on this drone. Begins disabled."
|
||||
set category = "Hivebot"
|
||||
|
||||
if(!active_signal)
|
||||
src.visible_message(SPAN_CULT("\The [src] begins to emit a low, humming sound..."),
|
||||
SPAN_CULT("You begin to transmit an invasive signal, subverting nearby synthetics."),
|
||||
SPAN_CULT("You hear a low humming..."))
|
||||
active_signal = TRUE
|
||||
else
|
||||
src.visible_message(SPAN_CULT("\The [src] abruptly ceases to emit a low, humming sound..."),
|
||||
SPAN_CULT("You cease transmitting the signal."),
|
||||
SPAN_CULT("A low humming noise abruptly cuts out!"))
|
||||
active_signal = FALSE
|
||||
@@ -0,0 +1,176 @@
|
||||
/obj/structure/machinery/r_n_d/material_silo
|
||||
name = "material silo"
|
||||
desc = "A centralized material store used by linked research fabricators."
|
||||
icon_state = "silo"
|
||||
|
||||
idle_power_usage = 30 WATTS
|
||||
|
||||
/// Total material capacity, measured in material units.
|
||||
var/max_material_storage = 800000
|
||||
|
||||
/// Materials shared by every fabricator connected to the same R&D console.
|
||||
var/list/materials = list(
|
||||
MATERIAL_STEEL = 0,
|
||||
MATERIAL_GLASS = 0,
|
||||
MATERIAL_GOLD = 0,
|
||||
MATERIAL_SILVER = 0,
|
||||
MATERIAL_PHORON = 0,
|
||||
MATERIAL_URANIUM = 0,
|
||||
MATERIAL_DIAMOND = 0,
|
||||
MATERIAL_PLASTEEL = 0,
|
||||
MATERIAL_ALUMINIUM = 0,
|
||||
MATERIAL_LEAD = 0
|
||||
)
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/upgrade_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
. += SPAN_NOTICE("\t- The shared storage capacity is <b>[max_material_storage / SHEET_MATERIAL_AMOUNT]</b> sheets.")
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/Initialize(mapload, d, populate_components, is_internal)
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/update_icon()
|
||||
. = ..()
|
||||
ClearOverlays()
|
||||
if(!(stat & (NOPOWER | BROKEN)))
|
||||
AddOverlays(emissive_appearance(icon, "[icon_state]_lights"))
|
||||
AddOverlays("[icon_state]_lights")
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/proc/TotalMaterials()
|
||||
SSmaterials.normalize_material_amounts(materials)
|
||||
var/total = 0
|
||||
for(var/material in materials)
|
||||
total += materials[material]
|
||||
return total
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/proc/get_material_amount(material_id)
|
||||
SSmaterials.normalize_material_amounts(materials)
|
||||
var/material = SSmaterials.material_to_path(material_id, FALSE)
|
||||
if(!material)
|
||||
material = material_id
|
||||
return materials[material] || 0
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/proc/has_material(material_id, amount)
|
||||
return get_material_amount(material_id) >= amount
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/proc/add_material(material_id, amount)
|
||||
if(amount <= 0)
|
||||
return 0
|
||||
var/material = SSmaterials.material_to_path(material_id, FALSE)
|
||||
if(!material)
|
||||
material = material_id
|
||||
if(!(material in materials))
|
||||
return 0
|
||||
var/accepted = min(amount, max_material_storage - TotalMaterials())
|
||||
if(accepted <= 0)
|
||||
return 0
|
||||
SSmaterials.add_material_amount(materials, material, accepted)
|
||||
update_linked_uis()
|
||||
return accepted
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/proc/remove_material(material_id, amount)
|
||||
if(amount <= 0)
|
||||
return TRUE
|
||||
var/material = SSmaterials.material_to_path(material_id, FALSE)
|
||||
if(!material)
|
||||
material = material_id
|
||||
if(!has_material(material, amount))
|
||||
return FALSE
|
||||
SSmaterials.remove_material_amount(materials, material, amount)
|
||||
update_linked_uis()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/proc/eject_material(material_id, requested_sheets)
|
||||
if(requested_sheets < 1)
|
||||
return FALSE
|
||||
var/material = SSmaterials.material_to_path(material_id, FALSE)
|
||||
if(!material)
|
||||
return FALSE
|
||||
var/available = round(get_material_amount(material) / SHEET_MATERIAL_AMOUNT)
|
||||
var/amount = min(requested_sheets, available)
|
||||
if(amount < 1)
|
||||
return FALSE
|
||||
var/stack_type = SSmaterials.material_stack_type(material)
|
||||
if(!stack_type)
|
||||
return FALSE
|
||||
var/obj/item/stack/material/stack = new stack_type(loc, amount)
|
||||
stack.update_icon()
|
||||
SSmaterials.remove_material_amount(materials, material, amount * SHEET_MATERIAL_AMOUNT)
|
||||
update_linked_uis()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/proc/wake_linked_fabricators()
|
||||
linked_console?.dispatch_fabrication_jobs()
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/proc/update_linked_uis()
|
||||
if(!linked_console)
|
||||
return
|
||||
SStgui.update_uis(linked_console)
|
||||
for(var/obj/structure/machinery/r_n_d/fabricator/fabricator as anything in linked_console.linked_fabricators)
|
||||
SStgui.update_uis(fabricator)
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/attackby(obj/item/attacking_item, mob/user)
|
||||
if(user.a_intent == I_HURT)
|
||||
return ..()
|
||||
if(default_deconstruction_screwdriver(user, attacking_item))
|
||||
disconnect_console()
|
||||
return TRUE
|
||||
if(default_deconstruction_crowbar(user, attacking_item))
|
||||
return TRUE
|
||||
if(default_part_replacement(user, attacking_item))
|
||||
return TRUE
|
||||
if(panel_open)
|
||||
to_chat(user, SPAN_NOTICE("You can't load \the [src] while it's opened."))
|
||||
return TRUE
|
||||
if(!istype(attacking_item, /obj/item/stack/material))
|
||||
return ..()
|
||||
if(stat)
|
||||
return TRUE
|
||||
|
||||
var/obj/item/stack/material/stack = attacking_item
|
||||
if(!stack.default_type || !stack.material)
|
||||
to_chat(user, SPAN_WARNING("This stack cannot be stored."))
|
||||
return TRUE
|
||||
|
||||
var/material = SSmaterials.material_to_path(stack.default_type, FALSE)
|
||||
if(!material)
|
||||
material = stack.default_type
|
||||
if(!(material in materials))
|
||||
to_chat(user, SPAN_WARNING("\The [src] cannot hold [stack.material.name]."))
|
||||
return TRUE
|
||||
|
||||
var/max_value = min(stack.get_amount(), round((max_material_storage - TotalMaterials()) / SHEET_MATERIAL_AMOUNT))
|
||||
if(max_value < 1)
|
||||
to_chat(user, SPAN_NOTICE("\The [src] is full."))
|
||||
return TRUE
|
||||
|
||||
var/amount = tgui_input_number(user, "How many sheets do you want to add?", "Add sheets", min(10, max_value), max_value = max_value, min_value = 1, round_value = TRUE)
|
||||
if(!amount || !Adjacent(user))
|
||||
return TRUE
|
||||
|
||||
use_power_oneoff(max(1000, SHEET_MATERIAL_AMOUNT * amount / 10))
|
||||
if(do_after(user, 1.6 SECONDS) && stack.use(amount))
|
||||
SSmaterials.add_material_amount(materials, material, amount * SHEET_MATERIAL_AMOUNT)
|
||||
to_chat(user, SPAN_NOTICE("You add [amount] sheet\s of [stack.material.name] to \the [src]."))
|
||||
update_linked_uis()
|
||||
wake_linked_fabricators()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/dismantle()
|
||||
SSmaterials.normalize_material_amounts(materials)
|
||||
for(var/material in materials)
|
||||
var/sheets = round(materials[material] / SHEET_MATERIAL_AMOUNT)
|
||||
if(sheets < 1)
|
||||
continue
|
||||
var/stack_type = SSmaterials.material_stack_type(material)
|
||||
if(!stack_type)
|
||||
continue
|
||||
var/obj/item/stack/material/stack = new stack_type(loc, sheets)
|
||||
stack.update_icon()
|
||||
..()
|
||||
|
||||
/obj/structure/machinery/r_n_d/material_silo/proc/disconnect_console()
|
||||
if(linked_console)
|
||||
linked_console.linked_silo = null
|
||||
linked_console = null
|
||||
@@ -0,0 +1,156 @@
|
||||
/obj/structure/machinery/r_n_d/fabricator/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"
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 5000
|
||||
req_access = list(ACCESS_ROBOTICS)
|
||||
component_types = list(
|
||||
/obj/item/circuitboard/mechfab,
|
||||
/obj/item/stock_parts/manipulator,
|
||||
/obj/item/stock_parts/micro_laser,
|
||||
/obj/item/stock_parts/console_screen
|
||||
)
|
||||
manufacturer = "hephaestus"
|
||||
build_type = MECHFAB
|
||||
product_offset = TRUE
|
||||
|
||||
fabrication_loop_type = /datum/looping_sound/synth_fab
|
||||
|
||||
/// Manufacturer used for the currently assigned prosthetic job.
|
||||
var/limb_manufacturer = PROSTHETIC_IND
|
||||
|
||||
/obj/structure/machinery/r_n_d/fabricator/mecha_part_fabricator/LateInitialize()
|
||||
. = ..()
|
||||
if(!linked_console)
|
||||
for(var/obj/structure/machinery/computer/rdconsole/console in range(3, src))
|
||||
console.SyncRDevices()
|
||||
if(linked_console)
|
||||
break
|
||||
|
||||
/obj/structure/machinery/r_n_d/fabricator/mecha_part_fabricator/upgrade_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
. += "- Materials are drawn from the research material silo linked to the same R&D console."
|
||||
. += "- 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/r_n_d/fabricator/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/r_n_d/fabricator/mecha_part_fabricator/Initialize()
|
||||
. = ..()
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/structure/machinery/r_n_d/fabricator/mecha_part_fabricator/update_icon()
|
||||
ClearOverlays()
|
||||
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")
|
||||
|
||||
/obj/structure/machinery/r_n_d/fabricator/mecha_part_fabricator/RefreshParts()
|
||||
..()
|
||||
var/manipulator_rating = 0
|
||||
for(var/obj/item/stock_parts/manipulator/manipulator in component_parts)
|
||||
manipulator_rating += manipulator.rating
|
||||
mat_efficiency = 1 - (manipulator_rating - 1) / 4
|
||||
|
||||
var/laser_rating = 0
|
||||
for(var/obj/item/stock_parts/micro_laser/laser in component_parts)
|
||||
laser_rating += laser.rating
|
||||
production_speed = max(1, laser_rating)
|
||||
|
||||
/obj/structure/machinery/r_n_d/fabricator/mecha_part_fabricator/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
if(!allowed(user))
|
||||
to_chat(user, SPAN_WARNING("Access denied."))
|
||||
return
|
||||
do_hair_pull(user)
|
||||
|
||||
var/cancelled = FALSE
|
||||
SEND_SIGNAL(user, COMSIG_USE_MECH_FAB, &cancelled)
|
||||
if(cancelled)
|
||||
return
|
||||
|
||||
/obj/structure/machinery/r_n_d/fabricator/mecha_part_fabricator/on_product_completed(obj/new_item, datum/design/design_to_build, datum/research_fabrication_job/job)
|
||||
visible_message("\The <b>[src]</b> pings, indicating that \the [new_item] is complete.", "You hear a ping.", intent_message = PING_SOUND)
|
||||
|
||||
/obj/structure/machinery/r_n_d/fabricator/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/r_n_d/fabricator/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\"")
|
||||
|
||||
/obj/structure/machinery/r_n_d/fabricator/mecha_part_fabricator/on_job_started(datum/research_fabrication_job/job)
|
||||
limb_manufacturer = job?.manufacturer
|
||||
|
||||
/obj/structure/machinery/r_n_d/fabricator/mecha_part_fabricator/on_job_cleared()
|
||||
limb_manufacturer = PROSTHETIC_IND
|
||||
@@ -0,0 +1,236 @@
|
||||
/datum/tgui_module/persistence_panel/ui_interact(mob/user, var/datum/tgui/ui)
|
||||
if(!can_use_persistence_panel(user))
|
||||
return
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "PersistencePanel", "Persistence Panel", 900, 700)
|
||||
ui.open()
|
||||
|
||||
/datum/tgui_module/persistence_panel/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["status_initialized"] = SSpersistence.init_success
|
||||
data["saving_active"] = !SSpersistence.prevent_saving
|
||||
data["objects_tracked"] = length(SSpersistence.object_track_register)
|
||||
data["records_cached"] = SSpersistence.history_cache_count
|
||||
data["generics_cached"] = length(SSpersistence.generic_cache)
|
||||
data["is_admin"] = check_rights(R_ADMIN, 0, user)
|
||||
|
||||
return data
|
||||
|
||||
/datum/tgui_module/persistence_panel/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["objects"] = get_tracked_objects_data()
|
||||
data["records"] = get_history_records_data()
|
||||
data["generics"] = get_generic_records_data()
|
||||
|
||||
return data
|
||||
|
||||
/datum/tgui_module/persistence_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
// Instead of return TRUE for a regular update, return FALSE and call ui.send_update() before.
|
||||
// Returning TRUE will cause static_ui_data to be sent, which in this panel is costly.
|
||||
|
||||
if(!can_use_persistence_panel(ui.user)) // Code behind permissions check
|
||||
return FALSE
|
||||
|
||||
if(action == "toggle_saving") // Toggle persistence saving at round end
|
||||
if(!check_rights(R_ADMIN))
|
||||
return FALSE
|
||||
|
||||
var/message = ""
|
||||
var/options = list()
|
||||
if(SSpersistence.prevent_saving)
|
||||
message = "The persistence subsystem will NOT save at the end of the round. Do you want to re-enable it?"
|
||||
options = list("Re-enable saving", "Cancel")
|
||||
else
|
||||
message = "The persistence subsystem will save at the end of the round. Do you want to prevent this? This can be un-done before the round ends."
|
||||
options = list("Prevent saving", "Cancel")
|
||||
|
||||
var/confirm = tgui_alert(usr, message, "Toggle Persistence Saving", options)
|
||||
if(confirm == "Prevent saving")
|
||||
SSpersistence.prevent_saving = TRUE
|
||||
to_world(FONT_LARGE(EXAMINE_BLOCK_RED("Persistence saving at the end of the round has been [SPAN_BOLD(SPAN_WARNING("disabled"))] by an administrator.")))
|
||||
log_and_message_admins("has toggled persistence saving at round end, it is now disabled", usr)
|
||||
else if (confirm == "Re-enable saving")
|
||||
SSpersistence.prevent_saving = FALSE
|
||||
to_world(FONT_LARGE(EXAMINE_BLOCK_RED("Persistence saving at the end of the round has been [SPAN_BOLD(SPAN_GOOD("re-enabled"))] by an administrator.")))
|
||||
log_and_message_admins("has toggled persistence saving at round end, it is now re-enabled", usr)
|
||||
|
||||
ui.send_update()
|
||||
return FALSE
|
||||
|
||||
if(action == "refresh") // Full data pull
|
||||
return TRUE
|
||||
|
||||
if (action == "jump") // Object jump
|
||||
var/atom/target = locate(params["ref"])
|
||||
if(!target || !istype(target))
|
||||
to_chat(ui.user, SPAN_WARNING("Object can no longer be found."))
|
||||
return FALSE
|
||||
|
||||
var/turf/T = get_turf(target)
|
||||
if(!T)
|
||||
to_chat(ui.user, SPAN_WARNING("Object can no longer be found."))
|
||||
return FALSE
|
||||
|
||||
var/client/C = ui.user?.client
|
||||
if(!C)
|
||||
return FALSE
|
||||
if(!isghost(usr))
|
||||
C.admin_ghost()
|
||||
C.jumptocoord(T.x, T.y, T.z)
|
||||
return FALSE
|
||||
|
||||
if(action == "edit") // Object VV
|
||||
var/client/C = ui.user?.client
|
||||
if(!C)
|
||||
return FALSE
|
||||
|
||||
var/atom/target = locate(params["ref"])
|
||||
if(!target || !istype(target))
|
||||
to_chat(ui.user, SPAN_WARNING("object can no longer be found."))
|
||||
return FALSE
|
||||
|
||||
C.debug_variables(target)
|
||||
return FALSE
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/tgui_module/persistence_panel/proc/get_tracked_objects_data()
|
||||
var/list/objects = list()
|
||||
for(var/obj/track in SSpersistence.object_track_register)
|
||||
var/turf/T = get_turf(track)
|
||||
objects += list(list(
|
||||
"ref" = REF(track), // Needed for VV action
|
||||
"type" = "[track.type]",
|
||||
"name" = track.name,
|
||||
"x" = T?.x || 0,
|
||||
"y" = T?.y || 0,
|
||||
"z" = T?.z || 0,
|
||||
"created_at" = track.persistent_objects_created_at,
|
||||
"expires_at" = track.persistent_objects_expires_at
|
||||
))
|
||||
return objects
|
||||
|
||||
/datum/tgui_module/persistence_panel/proc/get_history_records_data()
|
||||
var/list/history_types = typesof(/singleton/persistent_type/history) - list(/singleton/persistent_type/history, /singleton/persistent_type/history/character)
|
||||
var/list/records = list()
|
||||
|
||||
for(var/type_path in history_types)
|
||||
var/singleton/persistent_type/history/type_instance = GET_SINGLETON(type_path)
|
||||
if(!type_instance)
|
||||
continue
|
||||
|
||||
records += list(build_history_type_data(type_instance))
|
||||
|
||||
return records
|
||||
|
||||
/datum/tgui_module/persistence_panel/proc/build_history_type_data(var/singleton/persistent_type/history/type_instance)
|
||||
var/list/type_attribute_groups = SSpersistence.historyGetAllRecordsForAllAttributes(type_instance, TRUE)
|
||||
if(!type_attribute_groups)
|
||||
type_attribute_groups = list()
|
||||
|
||||
var/list/attribute_groups_history = list()
|
||||
for(var/attribute_group in type_attribute_groups)
|
||||
attribute_groups_history += list(build_history_attribute_group_data(type_instance, attribute_group))
|
||||
|
||||
return list(
|
||||
"type" = get_persistent_type_display_name(type_instance),
|
||||
"title" = type_instance.title,
|
||||
"description" = type_instance.description,
|
||||
"requires_attribute" = type_instance.requires_attribute,
|
||||
"attributes" = attribute_groups_history
|
||||
)
|
||||
|
||||
/datum/tgui_module/persistence_panel/proc/build_history_attribute_group_data(var/singleton/persistent_type/history/type_instance, var/list/attribute_group)
|
||||
var/attribute = attribute_group["attribute"]
|
||||
var/list/attribute_records = attribute_group["records"] || list()
|
||||
var/list/record_items = list()
|
||||
|
||||
for(var/datum/persistent_record/record in attribute_records)
|
||||
record_items += list(list(
|
||||
"created_at" = record.created_at,
|
||||
"game_id" = record.game_id,
|
||||
"value" = "[record.value]"
|
||||
))
|
||||
|
||||
var/attribute_value = attribute
|
||||
if(istype(type_instance, /singleton/persistent_type/history/character))
|
||||
// Character history is a special case, we want to show the character name instead of the ID
|
||||
attribute_value = SSpersistence.historyGetCharnameByID(attribute)
|
||||
|
||||
return list(
|
||||
"attribute" = attribute_value,
|
||||
"records" = record_items
|
||||
)
|
||||
|
||||
/datum/tgui_module/persistence_panel/proc/get_generic_records_data()
|
||||
var/list/generics_by_type = list()
|
||||
var/custom_types = typesof(/singleton/persistent_type/generic) - /singleton/persistent_type/generic
|
||||
|
||||
for(var/type_path in custom_types)
|
||||
var/singleton/persistent_type/generic/type_instance = GET_SINGLETON(type_path)
|
||||
if(!type_instance)
|
||||
continue
|
||||
|
||||
var/type_key = "[type_instance.type]"
|
||||
if(!generics_by_type[type_key])
|
||||
generics_by_type[type_key] = build_generic_type_data(type_instance)
|
||||
|
||||
append_generic_attribute_data(type_instance, generics_by_type[type_key]["attributes"])
|
||||
|
||||
var/list/generics = list()
|
||||
for(var/type_key in generics_by_type)
|
||||
generics += list(generics_by_type[type_key])
|
||||
|
||||
return generics
|
||||
|
||||
/datum/tgui_module/persistence_panel/proc/build_generic_type_data(var/singleton/persistent_type/generic/type_instance)
|
||||
var/list/type_parts = return_typenames(type_instance.type)
|
||||
return list(
|
||||
"type" = type_parts[length(type_parts)],
|
||||
"title" = type_instance.title,
|
||||
"description" = type_instance.description,
|
||||
"requires_attribute" = type_instance.requires_attribute,
|
||||
"attributes" = list()
|
||||
)
|
||||
|
||||
/datum/tgui_module/persistence_panel/proc/append_generic_attribute_data(var/singleton/persistent_type/generic/type_instance, var/list/attribute_groups_generic)
|
||||
if(type_instance.requires_attribute)
|
||||
var/list/attributes = SSpersistence.genericGetAllAttributesForType(type_instance)
|
||||
for(var/attribute in attributes)
|
||||
var/datum/persistent_generic/generic_entry = SSpersistence.genericLoad(type_instance, attribute, TRUE)
|
||||
if(!generic_entry)
|
||||
continue
|
||||
|
||||
attribute_groups_generic += list(list(
|
||||
"attribute" = attribute,
|
||||
"created_at" = generic_entry.created_at,
|
||||
"expires_at" = generic_entry.expires_at,
|
||||
"json" = json_encode(generic_entry.content)
|
||||
))
|
||||
return
|
||||
|
||||
var/datum/persistent_generic/generic_entry = SSpersistence.genericLoad(type_instance, null, TRUE)
|
||||
if(generic_entry)
|
||||
attribute_groups_generic += list(list(
|
||||
"attribute" = null,
|
||||
"created_at" = generic_entry.created_at,
|
||||
"expires_at" = generic_entry.expires_at,
|
||||
"json" = json_encode(generic_entry.content)
|
||||
))
|
||||
|
||||
/datum/tgui_module/persistence_panel/proc/get_persistent_type_display_name(var/singleton/persistent_type/type_instance)
|
||||
var/list/type_parts = return_typenames(type_instance.type)
|
||||
var/type_name = type_parts[length(type_parts)]
|
||||
if(istype(type_instance, /singleton/persistent_type/history/character))
|
||||
return "Character - [type_name]"
|
||||
|
||||
return type_name
|
||||
|
||||
/datum/tgui_module/persistence_panel/proc/can_use_persistence_panel(var/mob/user)
|
||||
return check_rights(R_ADMIN|R_MOD|R_DEV, 0, user)
|
||||
Reference in New Issue
Block a user