mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-31 09:08:30 +01:00
# Conflicts: # .github/CODEOWNERS # .github/workflows/compile_changelogs.yml # .github/workflows/stale.yml # SQL/database_changelog.md # _maps/map_files/CatwalkStation/CatwalkStation_2023.dmm # code/__DEFINES/atom_hud.dm # code/__DEFINES/inventory.dm # code/__DEFINES/mobs.dm # code/__DEFINES/species_clothing_paths.dm # code/__DEFINES/subsystems.dm # code/__DEFINES/surgery.dm # code/__HELPERS/global_lists.dm # code/_globalvars/lists/maintenance_loot.dm # code/_globalvars/traits/_traits.dm # code/controllers/subsystem/minor_mapping.dm # code/controllers/subsystem/processing/quirks.dm # code/controllers/subsystem/shuttle.dm # code/datums/components/palette.dm # code/datums/components/surgery_initiator.dm # code/datums/diseases/advance/advance.dm # code/datums/hud.dm # code/datums/mood.dm # code/datums/mutations/chameleon.dm # code/datums/quirks/negative_quirks/nyctophobia.dm # code/datums/status_effects/debuffs/debuffs.dm # code/datums/status_effects/debuffs/drunk.dm # code/datums/status_effects/debuffs/slime/slime_leech.dm # code/datums/weather/weather.dm # code/game/data_huds.dm # code/game/objects/items.dm # code/game/objects/items/devices/scanners/health_analyzer.dm # code/game/objects/items/frog_statue.dm # code/game/objects/items/rcd/RLD.dm # code/game/objects/items/robot/items/hypo.dm # code/game/objects/items/stacks/medical.dm # code/game/objects/items/stacks/wrap.dm # code/game/objects/items/storage/garment.dm # code/game/objects/items/tools/medical/defib.dm # code/game/objects/items/weaponry.dm # code/game/objects/items/weaponry/melee/misc.dm # code/game/objects/structures/crates_lockers/closets/secure/security.dm # code/game/objects/structures/curtains.dm # code/game/objects/structures/dresser.dm # code/game/objects/structures/girders.dm # code/game/objects/structures/maintenance.dm # code/game/objects/structures/mirror.dm # code/modules/admin/greyscale_modify_menu.dm # code/modules/admin/verbs/light_debug.dm # code/modules/antagonists/ashwalker/ashwalker.dm # code/modules/antagonists/heretic/knowledge/starting_lore.dm # code/modules/antagonists/ninja/ninjaDrainAct.dm # code/modules/art/paintings.dm # code/modules/client/preferences.dm # code/modules/client/verbs/ooc.dm # code/modules/clothing/head/wig.dm # code/modules/events/disease_outbreak.dm # code/modules/holodeck/holo_effect.dm # code/modules/jobs/job_types/head_of_security.dm # code/modules/jobs/job_types/security_officer.dm # code/modules/library/skill_learning/generic_skillchips/point.dm # code/modules/mining/lavaland/ash_flora.dm # code/modules/mining/lavaland/mining_loot/megafauna/ash_drake.dm # code/modules/mob/dead/new_player/new_player.dm # code/modules/mob/living/basic/guardian/guardian.dm # code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm # code/modules/mob/living/carbon/carbon.dm # code/modules/mob/living/carbon/human/human.dm # code/modules/mob/living/carbon/human/human_defines.dm # code/modules/mob/living/carbon/life.dm # code/modules/mob/living/living.dm # code/modules/mob/living/living_defines.dm # code/modules/mob/mob.dm # code/modules/mob_spawn/ghost_roles/mining_roles.dm # code/modules/mod/mod_control.dm # code/modules/mod/modules/modules_general.dm # code/modules/modular_computers/computers/item/computer_ui.dm # code/modules/paperwork/paper.dm # code/modules/paperwork/paperbin.dm # code/modules/power/lighting/light.dm # code/modules/projectiles/guns/energy/kinetic_accelerator.dm # code/modules/projectiles/projectile.dm # code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm # code/modules/reagents/chemistry/reagents/food_reagents.dm # code/modules/reagents/chemistry/reagents/other_reagents.dm # code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm # code/modules/research/xenobiology/crossbreeding/_clothing.dm # code/modules/research/xenobiology/crossbreeding/prismatic.dm # code/modules/surgery/advanced/brainwashing.dm # code/modules/surgery/advanced/lobotomy.dm # code/modules/surgery/amputation.dm # code/modules/surgery/blood_filter.dm # code/modules/surgery/bodyparts/_bodyparts.dm # code/modules/surgery/brain_surgery.dm # code/modules/surgery/cavity_implant.dm # code/modules/surgery/coronary_bypass.dm # code/modules/surgery/gastrectomy.dm # code/modules/surgery/healing.dm # code/modules/surgery/limb_augmentation.dm # code/modules/surgery/organ_manipulation.dm # code/modules/surgery/revival.dm # code/modules/surgery/sleeper_protocol.dm # code/modules/surgery/surgery_helpers.dm # code/modules/surgery/surgery_step.dm # code/modules/unit_tests/_unit_tests.dm # code/modules/unit_tests/designs.dm # code/modules/unit_tests/icon_state_worn.dm # code/modules/unit_tests/screenshots/screenshot_antag_icons_cultist.png # code/modules/unit_tests/screenshots/screenshot_antag_icons_headrevolutionary.png # code/modules/unit_tests/screenshots/screenshot_antag_icons_provocateur.png # code/modules/unit_tests/screenshots/screenshot_husk_body.png # code/modules/unit_tests/screenshots/screenshot_husk_body_missing_limbs.png # icons/map_icons/clothing/head/_head.dmi # icons/map_icons/clothing/shoes.dmi # icons/map_icons/items/_item.dmi # icons/mob/huds/hud.dmi # icons/mob/inhands/64x64_lefthand.dmi # icons/mob/inhands/64x64_righthand.dmi # icons/obj/machines/computer.dmi # tgui/packages/tgui/interfaces/OperatingComputer.jsx # tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferences/MainPage.tsx # tgui/packages/tgui/interfaces/PreferencesMenu/types.ts # tgui/packages/tgui/interfaces/SurgeryInitiator.tsx # tools/icon_cutter/check.py
387 lines
12 KiB
Plaintext
387 lines
12 KiB
Plaintext
|
|
|
|
///BSA unlocked by head ID swipes
|
|
GLOBAL_VAR_INIT(bsa_unlock, FALSE)
|
|
|
|
/* SKYRAT EDIT REMOVAL - MOVED TO MODULAR BSA_OVERHAUL
|
|
// Crew has to build a bluespace cannon
|
|
// Cargo orders part for high price
|
|
// Requires high amount of power
|
|
// Requires high level stock parts
|
|
/datum/station_goal/bluespace_cannon
|
|
name = "Bluespace Artillery"
|
|
|
|
/datum/station_goal/bluespace_cannon/get_report()
|
|
return list(
|
|
"<blockquote>Our military presence is inadequate in your sector.",
|
|
"We need you to construct BSA-[rand(1,99)] Artillery position aboard your station.",
|
|
"",
|
|
"Base parts are available for shipping via cargo.",
|
|
"-Nanotrasen Naval Command</blockquote>",
|
|
).Join("\n")
|
|
|
|
/datum/station_goal/bluespace_cannon/on_report()
|
|
//Unlock BSA parts
|
|
var/datum/supply_pack/engineering/bsa/P = SSshuttle.supply_packs[/datum/supply_pack/engineering/bsa]
|
|
P.order_flags |= ORDER_SPECIAL_ENABLED
|
|
|
|
/datum/station_goal/bluespace_cannon/check_completion()
|
|
if(..())
|
|
return TRUE
|
|
var/obj/machinery/bsa/full/B = locate()
|
|
if(B && !B.machine_stat)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/obj/machinery/bsa
|
|
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
|
density = TRUE
|
|
anchored = TRUE
|
|
|
|
/obj/machinery/bsa/wrench_act(mob/living/user, obj/item/tool)
|
|
. = ..()
|
|
default_unfasten_wrench(user, tool, time = 1 SECONDS)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/bsa/back
|
|
name = "Bluespace Artillery Generator"
|
|
desc = "Generates cannon pulse. Needs to be linked with a fusor."
|
|
icon_state = "power_box"
|
|
|
|
/obj/machinery/bsa/back/Initialize(mapload)
|
|
. = ..()
|
|
AddElement(/datum/element/simple_rotation)
|
|
|
|
/obj/machinery/bsa/back/multitool_act(mob/living/user, obj/item/multitool/M)
|
|
M.set_buffer(src)
|
|
balloon_alert(user, "saved to multitool buffer")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/bsa/front
|
|
name = "Bluespace Artillery Bore"
|
|
desc = "Do not stand in front of cannon during operation. Needs to be linked with a fusor."
|
|
icon_state = "emitter_center"
|
|
|
|
/obj/machinery/bsa/front/Initialize(mapload)
|
|
. = ..()
|
|
AddElement(/datum/element/simple_rotation)
|
|
|
|
/obj/machinery/bsa/front/multitool_act(mob/living/user, obj/item/multitool/M)
|
|
M.set_buffer(src)
|
|
balloon_alert(user, "saved to multitool buffer")
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/bsa/middle
|
|
name = "Bluespace Artillery Fusor"
|
|
desc = "Contents classified by Nanotrasen Naval Command. Needs to be linked with the other BSA parts using a multitool."
|
|
icon_state = "fuel_chamber"
|
|
var/datum/weakref/back_ref
|
|
var/datum/weakref/front_ref
|
|
|
|
/obj/machinery/bsa/middle/Initialize(mapload)
|
|
. = ..()
|
|
AddElement(/datum/element/simple_rotation)
|
|
|
|
/obj/machinery/bsa/middle/multitool_act(mob/living/user, obj/item/multitool/tool)
|
|
. = NONE
|
|
|
|
if(istype(tool.buffer, /obj/machinery/bsa/back))
|
|
back_ref = WEAKREF(tool.buffer)
|
|
to_chat(user, span_notice("You link [src] with [tool.buffer]."))
|
|
tool.set_buffer(null)
|
|
return ITEM_INTERACT_SUCCESS
|
|
else if(istype(tool.buffer, /obj/machinery/bsa/front))
|
|
front_ref = WEAKREF(tool.buffer)
|
|
to_chat(user, span_notice("You link [src] with [tool.buffer]."))
|
|
tool.set_buffer(null)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/machinery/bsa/middle/proc/check_completion()
|
|
var/obj/machinery/bsa/front/front = front_ref?.resolve()
|
|
var/obj/machinery/bsa/back/back = back_ref?.resolve()
|
|
if(!front || !back)
|
|
return "No linked parts detected!"
|
|
if(!front.anchored || !back.anchored || !anchored)
|
|
return "Linked parts unwrenched!"
|
|
if(front.y != y || back.y != y || !(front.x > x && back.x < x || front.x < x && back.x > x) || front.z != z || back.z != z)
|
|
return "Parts misaligned!"
|
|
if(!has_space())
|
|
return "Not enough free space!"
|
|
|
|
/obj/machinery/bsa/middle/proc/has_space()
|
|
var/cannon_dir = get_cannon_direction()
|
|
var/width = 10
|
|
var/offset
|
|
switch(cannon_dir)
|
|
if(EAST)
|
|
offset = -4
|
|
if(WEST)
|
|
offset = -6
|
|
else
|
|
return FALSE
|
|
|
|
var/turf/base = get_turf(src)
|
|
for(var/turf/T as anything in CORNER_BLOCK_OFFSET(base, width, 3, offset, -1))
|
|
if(T.density || isspaceturf(T))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/machinery/bsa/middle/proc/get_cannon_direction()
|
|
var/obj/machinery/bsa/front/front = front_ref?.resolve()
|
|
var/obj/machinery/bsa/back/back = back_ref?.resolve()
|
|
if(!front || !back)
|
|
return
|
|
if(front.x > x && back.x < x)
|
|
return EAST
|
|
else if(front.x < x && back.x > x)
|
|
return WEST
|
|
|
|
|
|
/obj/machinery/bsa/full
|
|
name = "Bluespace Artillery"
|
|
desc = "Long range bluespace artillery."
|
|
icon = 'icons/obj/machines/cannon.dmi'
|
|
icon_state = "cannon_west"
|
|
var/static/mutable_appearance/top_layer
|
|
var/ex_power = 3
|
|
var/power_used_per_shot = 2000000 //enough to kil standard apc - todo : make this use wires instead and scale explosion power with it
|
|
pixel_y = -32
|
|
pixel_x = -192
|
|
bound_width = 352
|
|
bound_x = -192
|
|
appearance_flags = LONG_GLIDE //Removes default TILE_BOUND
|
|
|
|
/obj/machinery/bsa/full/wrench_act(mob/living/user, obj/item/I)
|
|
return FALSE
|
|
|
|
/obj/machinery/bsa/full/proc/get_front_turf()
|
|
switch(dir)
|
|
if(WEST)
|
|
return locate(x - 7,y,z)
|
|
if(EAST)
|
|
return locate(x + 7,y,z)
|
|
return get_turf(src)
|
|
|
|
/obj/machinery/bsa/full/proc/get_back_turf()
|
|
switch(dir)
|
|
if(WEST)
|
|
return locate(x + 5,y,z)
|
|
if(EAST)
|
|
return locate(x - 5,y,z)
|
|
return get_turf(src)
|
|
|
|
/obj/machinery/bsa/full/proc/get_target_turf()
|
|
switch(dir)
|
|
if(WEST)
|
|
return locate(1,y,z)
|
|
if(EAST)
|
|
return locate(world.maxx,y,z)
|
|
return get_turf(src)
|
|
|
|
/obj/machinery/bsa/full/Initialize(mapload, cannon_direction = WEST)
|
|
. = ..()
|
|
switch(cannon_direction)
|
|
if(WEST)
|
|
setDir(WEST)
|
|
icon_state = "cannon_west"
|
|
if(EAST)
|
|
setDir(EAST)
|
|
pixel_x = -128
|
|
bound_x = -128
|
|
icon_state = "cannon_east"
|
|
get_layer()
|
|
|
|
/obj/machinery/bsa/full/proc/get_layer()
|
|
top_layer = mutable_appearance(icon, layer = ABOVE_MOB_LAYER)
|
|
switch(dir)
|
|
if(WEST)
|
|
top_layer.icon_state = "top_west"
|
|
if(EAST)
|
|
top_layer.icon_state = "top_east"
|
|
add_overlay(top_layer)
|
|
|
|
/obj/machinery/bsa/full/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
|
|
if(same_z_layer)
|
|
return ..()
|
|
cut_overlay(top_layer)
|
|
get_layer()
|
|
return ..()
|
|
|
|
/obj/machinery/bsa/full/proc/fire(mob/user, turf/bullseye)
|
|
var/turf/point = get_front_turf()
|
|
var/turf/target = get_target_turf()
|
|
var/atom/blocker
|
|
for(var/T in get_line(get_step(point, dir), target))
|
|
var/turf/tile = T
|
|
if(SEND_SIGNAL(tile, COMSIG_ATOM_BSA_BEAM) & COMSIG_ATOM_BLOCKS_BSA_BEAM)
|
|
blocker = tile
|
|
else
|
|
for(var/AM in tile)
|
|
var/atom/movable/stuff = AM
|
|
if(SEND_SIGNAL(stuff, COMSIG_ATOM_BSA_BEAM) & COMSIG_ATOM_BLOCKS_BSA_BEAM)
|
|
blocker = stuff
|
|
break
|
|
if(blocker)
|
|
target = tile
|
|
break
|
|
else
|
|
SSexplosions.highturf += tile //also fucks everything else on the turf
|
|
point.Beam(target, icon_state = "bsa_beam", time = 5 SECONDS, maxdistance = world.maxx) //ZZZAP
|
|
new /obj/effect/temp_visual/bsa_splash(point, dir)
|
|
|
|
notify_ghosts(
|
|
"The Bluespace Artillery has been fired!",
|
|
source = bullseye,
|
|
header = "KABOOM!",
|
|
)
|
|
|
|
if(!blocker)
|
|
message_admins("[ADMIN_LOOKUPFLW(user)] has launched a bluespace artillery strike targeting [ADMIN_VERBOSEJMP(bullseye)].")
|
|
user.log_message("has launched a bluespace artillery strike targeting [AREACOORD(bullseye)].", LOG_GAME)
|
|
explosion(bullseye, devastation_range = ex_power, heavy_impact_range = ex_power*2, light_impact_range = ex_power*4, explosion_cause = src)
|
|
new /obj/effect/temp_visual/bsa_impact(bullseye)
|
|
else
|
|
message_admins("[ADMIN_LOOKUPFLW(user)] has launched a bluespace artillery strike targeting [ADMIN_VERBOSEJMP(bullseye)] but it was blocked by [blocker] at [ADMIN_VERBOSEJMP(target)].")
|
|
user.log_message("has launched a bluespace artillery strike targeting [AREACOORD(bullseye)] but it was blocked by [blocker] at [AREACOORD(target)].", LOG_GAME)
|
|
|
|
/obj/structure/filler
|
|
name = "big machinery part"
|
|
density = TRUE
|
|
anchored = TRUE
|
|
invisibility = INVISIBILITY_ABSTRACT
|
|
var/obj/machinery/parent
|
|
|
|
/obj/structure/filler/ex_act()
|
|
return FALSE
|
|
|
|
/obj/machinery/computer/bsa_control
|
|
name = "bluespace artillery control"
|
|
use_power = NO_POWER_USE
|
|
circuit = /obj/item/circuitboard/computer/bsa_control
|
|
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
|
icon_state = "control_boxp"
|
|
icon_keyboard = null
|
|
icon_screen = null
|
|
|
|
var/datum/weakref/cannon_ref
|
|
var/notice
|
|
var/target
|
|
var/area_aim = FALSE //should also show areas for targeting
|
|
|
|
/obj/machinery/computer/bsa_control/ui_state(mob/user)
|
|
return GLOB.physical_state
|
|
|
|
/obj/machinery/computer/bsa_control/ui_interact(mob/user, datum/tgui/ui)
|
|
. = ..()
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "BluespaceArtillery", name)
|
|
ui.open()
|
|
|
|
/obj/machinery/computer/bsa_control/ui_data()
|
|
var/obj/machinery/bsa/full/cannon = cannon_ref?.resolve()
|
|
var/list/data = list()
|
|
data["connected"] = cannon
|
|
data["notice"] = notice
|
|
data["unlocked"] = GLOB.bsa_unlock
|
|
if(target)
|
|
data["target"] = get_target_name()
|
|
return data
|
|
|
|
/obj/machinery/computer/bsa_control/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
|
|
switch(action)
|
|
if("build")
|
|
cannon_ref = WEAKREF(deploy())
|
|
. = TRUE
|
|
if("fire")
|
|
var/obj/machinery/bsa/full/cannon = cannon_ref.resolve()
|
|
if(cannon.use_energy(cannon.power_used_per_shot, force = FALSE))
|
|
fire(ui.user)
|
|
else
|
|
to_chat(ui.user, span_warning("Insufficient power!"))
|
|
. = TRUE
|
|
if("recalibrate")
|
|
calibrate(usr)
|
|
. = TRUE
|
|
update_appearance()
|
|
|
|
/obj/machinery/computer/bsa_control/proc/calibrate(mob/user)
|
|
if(!GLOB.bsa_unlock)
|
|
return
|
|
var/list/gps_locators = list()
|
|
for(var/datum/component/gps/G in GLOB.GPS_list) //nulls on the list somehow
|
|
if(G.tracking)
|
|
gps_locators[G.gpstag] = G
|
|
|
|
var/list/options = gps_locators
|
|
if(area_aim)
|
|
options += GLOB.teleportlocs
|
|
var/victim = tgui_input_list(user, "Select target", "Artillery Targeting", options)
|
|
if(isnull(victim))
|
|
return
|
|
if(isnull(options[victim]))
|
|
return
|
|
target = options[victim]
|
|
log_game("[key_name(user)] has aimed the bluespace artillery strike at [target].")
|
|
|
|
|
|
/obj/machinery/computer/bsa_control/proc/get_target_name()
|
|
if(istype(target, /area))
|
|
return get_area_name(target, TRUE)
|
|
else if(istype(target, /datum/component/gps))
|
|
var/datum/component/gps/G = target
|
|
return G.gpstag
|
|
|
|
/obj/machinery/computer/bsa_control/proc/get_impact_turf()
|
|
if(obj_flags & EMAGGED)
|
|
return get_turf(src)
|
|
else if(istype(target, /area))
|
|
return pick(get_area_turfs(target))
|
|
else if(istype(target, /datum/component/gps))
|
|
var/datum/component/gps/G = target
|
|
return get_turf(G.parent)
|
|
|
|
/obj/machinery/computer/bsa_control/proc/fire(mob/user)
|
|
var/obj/machinery/bsa/full/cannon = cannon_ref?.resolve()
|
|
if(!cannon)
|
|
notice = "No Cannon Exists!"
|
|
return
|
|
if(cannon.machine_stat)
|
|
notice = "Cannon unpowered!"
|
|
return
|
|
notice = null
|
|
var/turf/target_turf = get_impact_turf()
|
|
cannon.fire(user, target_turf)
|
|
|
|
/obj/machinery/computer/bsa_control/proc/deploy(force=FALSE)
|
|
var/obj/machinery/bsa/full/prebuilt = locate() in range(7) //In case of adminspawn
|
|
if(prebuilt)
|
|
return prebuilt
|
|
|
|
var/obj/machinery/bsa/middle/centerpiece = locate() in range(7)
|
|
if(!centerpiece)
|
|
notice = "No BSA parts detected nearby."
|
|
return null
|
|
notice = centerpiece.check_completion()
|
|
if(notice)
|
|
return null
|
|
//Totally nanite construction system not an immersion breaking spawning
|
|
do_smoke(4, get_turf(centerpiece), get_turf(centerpiece))
|
|
var/obj/machinery/bsa/full/cannon = new(get_turf(centerpiece),centerpiece.get_cannon_direction())
|
|
QDEL_NULL(centerpiece.front_ref)
|
|
QDEL_NULL(centerpiece.back_ref)
|
|
qdel(centerpiece)
|
|
return cannon
|
|
/obj/machinery/computer/bsa_control/emag_act(mob/user, obj/item/card/emag/emag_card)
|
|
if(obj_flags & EMAGGED)
|
|
return FALSE
|
|
obj_flags |= EMAGGED
|
|
balloon_alert(user, "rigged to explode")
|
|
to_chat(user, span_warning("You emag [src] and hear the focusing crystal short out. You get the feeling it wouldn't be wise to stand near [src] when the BSA fires..."))
|
|
return TRUE
|
|
*/
|