Adds point defense batteries to defend against meteors
- Creates a global meteors list to make it easier to find them. - Adds point defense mainframe, batteries, projectiles, circuitboards, and R&D designs. - Adds sound effects and icons for the new machines. - Original code and sprites ported from Baystation. Adtapted to our code, added icon states and QoL elements.
@@ -17,3 +17,4 @@
|
|||||||
#define COLOR_ASSEMBLY_HOT_PINK "#FF69B4"
|
#define COLOR_ASSEMBLY_HOT_PINK "#FF69B4"
|
||||||
|
|
||||||
#define COLOR_ASTEROID_ROCK "#735555"
|
#define COLOR_ASTEROID_ROCK "#735555"
|
||||||
|
#define COLOR_GOLD "#ffcc33"
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
GLOBAL_LIST_INIT(speech_toppings, list("|" = "i", "+" = "b", "_" = "u"))
|
GLOBAL_LIST_INIT(speech_toppings, list("|" = "i", "+" = "b", "_" = "u"))
|
||||||
|
GLOBAL_LIST_EMPTY(meteor_list)
|
||||||
|
|||||||
@@ -126,10 +126,10 @@
|
|||||||
// Multiply this and the hits var to get a rough idea of how penetrating a meteor is.
|
// Multiply this and the hits var to get a rough idea of how penetrating a meteor is.
|
||||||
var/wall_power = 100
|
var/wall_power = 100
|
||||||
|
|
||||||
/obj/effect/meteor/New()
|
/obj/effect/meteor/Initialize()
|
||||||
..()
|
. = ..()
|
||||||
z_original = z
|
z_original = z
|
||||||
|
GLOB.meteor_list += src
|
||||||
|
|
||||||
/obj/effect/meteor/Move()
|
/obj/effect/meteor/Move()
|
||||||
if(z != z_original || loc == dest)
|
if(z != z_original || loc == dest)
|
||||||
@@ -149,6 +149,7 @@
|
|||||||
|
|
||||||
/obj/effect/meteor/Destroy()
|
/obj/effect/meteor/Destroy()
|
||||||
walk(src,0) //this cancels the walk_towards() proc
|
walk(src,0) //this cancels the walk_towards() proc
|
||||||
|
GLOB.meteor_list -= src
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/obj/effect/meteor/New()
|
/obj/effect/meteor/New()
|
||||||
|
|||||||
341
code/game/machinery/pointdefense.dm
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
//
|
||||||
|
// Control computer for point defense batteries.
|
||||||
|
// Handles control UI, but also coordinates their fire to avoid overkill.
|
||||||
|
//
|
||||||
|
|
||||||
|
GLOBAL_LIST_BOILERPLATE(pointdefense_controllers, /obj/machinery/pointdefense_control)
|
||||||
|
GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense_control
|
||||||
|
name = "fire assist mainframe"
|
||||||
|
desc = "A specialized computer designed to synchronize a variety of weapon systems and a vessel's astronav data."
|
||||||
|
icon = 'icons/obj/pointdefense.dmi'
|
||||||
|
icon_state = "control"
|
||||||
|
density = TRUE
|
||||||
|
anchored = TRUE
|
||||||
|
circuit = /obj/item/weapon/circuitboard/pointdefense_control
|
||||||
|
var/list/targets = list() // Targets being engaged by associated batteries
|
||||||
|
var/ui_template = "pointdefense_control.tmpl"
|
||||||
|
var/id_tag = null
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense_control/Initialize(mapload)
|
||||||
|
. = ..()
|
||||||
|
if(id_tag)
|
||||||
|
//No more than 1 controller please.
|
||||||
|
for(var/thing in pointdefense_controllers)
|
||||||
|
var/obj/machinery/pointdefense_control/PC = thing
|
||||||
|
if(PC != src && PC.id_tag == id_tag)
|
||||||
|
warning("Two [src] with the same id_tag of [id_tag]")
|
||||||
|
id_tag = null
|
||||||
|
// TODO - Remove this bit once machines are converted to Initialize
|
||||||
|
if(ispath(circuit))
|
||||||
|
circuit = new circuit(src)
|
||||||
|
default_apply_parts()
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense_control/get_description_interaction()
|
||||||
|
. = ..()
|
||||||
|
if(!id_tag)
|
||||||
|
. += "[desc_panel_image("multitool")]to set ident tag"
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense_control/ui_interact(var/mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||||
|
if(ui_template)
|
||||||
|
var/list/data = build_ui_data()
|
||||||
|
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||||
|
if (!ui)
|
||||||
|
ui = new(user, src, ui_key, ui_template, name, 400, 600)
|
||||||
|
ui.set_initial_data(data)
|
||||||
|
ui.open()
|
||||||
|
ui.set_auto_update(1)
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense_control/attack_hand(mob/user)
|
||||||
|
if((. = ..()))
|
||||||
|
return
|
||||||
|
if(CanUseTopic(user, global.default_state) > STATUS_CLOSE)
|
||||||
|
ui_interact(user)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense_control/Topic(var/mob/user, var/href_list)
|
||||||
|
if((. = ..()))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(href_list["toggle_active"])
|
||||||
|
var/obj/machinery/pointdefense/PD = locate(href_list["toggle_active"])
|
||||||
|
if(!istype(PD))
|
||||||
|
return TOPIC_NOACTION
|
||||||
|
|
||||||
|
//if(!lan || !lan.is_connected(PD))
|
||||||
|
if(PD.id_tag != id_tag)
|
||||||
|
return TOPIC_NOACTION
|
||||||
|
|
||||||
|
if(!(get_z(PD) in GetConnectedZlevels(get_z(src))))
|
||||||
|
to_chat(user, "<span class='warning'>[PD] is not within control range.</span>")
|
||||||
|
return TOPIC_NOACTION
|
||||||
|
|
||||||
|
if(!PD.Activate()) //Activate() whilst the device is active will return false.
|
||||||
|
PD.Deactivate()
|
||||||
|
return TOPIC_REFRESH
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense_control/proc/build_ui_data()
|
||||||
|
var/list/data = list()
|
||||||
|
data["id"] = id_tag
|
||||||
|
data["name"] = name
|
||||||
|
var/list/turrets = list()
|
||||||
|
if(id_tag)
|
||||||
|
var/list/connected_z_levels = GetConnectedZlevels(get_z(src))
|
||||||
|
for(var/i = 1 to LAZYLEN(pointdefense_turrets))
|
||||||
|
var/obj/machinery/pointdefense/PD = pointdefense_turrets[i]
|
||||||
|
if(!(PD.id_tag == id_tag && get_z(PD) in connected_z_levels))
|
||||||
|
continue
|
||||||
|
var/list/turret = list()
|
||||||
|
turret["id"] = "#[i]"
|
||||||
|
turret["ref"] = "\ref[PD]"
|
||||||
|
turret["active"] = PD.active
|
||||||
|
turret["effective_range"] = PD.active ? "[PD.kill_range] meter\s" : "OFFLINE."
|
||||||
|
turret["reaction_wheel_delay"] = PD.active ? "[(PD.rotation_speed / (1 SECONDS))] second\s" : "OFFLINE."
|
||||||
|
turret["recharge_time"] = PD.active ? "[(PD.charge_cooldown / (1 SECONDS))] second\s" : "OFFLINE."
|
||||||
|
|
||||||
|
turrets += list(turret)
|
||||||
|
|
||||||
|
data["turrets"] = turrets
|
||||||
|
return data
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense_control/attackby(var/obj/item/W, var/mob/user)
|
||||||
|
if(W?.is_multitool())
|
||||||
|
var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text
|
||||||
|
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, physical_state))
|
||||||
|
// Check for duplicate controllers with this ID
|
||||||
|
for(var/thing in pointdefense_controllers)
|
||||||
|
var/obj/machinery/pointdefense_control/PC = thing
|
||||||
|
if(PC != src && PC.id_tag == id_tag)
|
||||||
|
to_chat(user, "<span class='warning'>The [new_ident] network already has a controller.</span>")
|
||||||
|
return
|
||||||
|
to_chat(user, "<span class='notice'>You register [src] with the [new_ident] network.</span>")
|
||||||
|
id_tag = new_ident
|
||||||
|
return
|
||||||
|
if(default_deconstruction_screwdriver(user, W))
|
||||||
|
return
|
||||||
|
if(default_deconstruction_crowbar(user, W))
|
||||||
|
return
|
||||||
|
if(default_part_replacement(user, W))
|
||||||
|
return
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
//
|
||||||
|
// The acutal point defense battery
|
||||||
|
//
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense
|
||||||
|
name = "\improper point defense battery"
|
||||||
|
icon = 'icons/obj/pointdefense.dmi'
|
||||||
|
icon_state = "pointdefense"
|
||||||
|
desc = "A Kuiper pattern anti-meteor battery. Capable of destroying most threats in a single salvo."
|
||||||
|
description_info = "Must have the same ident tag as a fire assist mainframe on the same facility."
|
||||||
|
density = TRUE
|
||||||
|
anchored = TRUE
|
||||||
|
circuit = /obj/item/weapon/circuitboard/pointdefense
|
||||||
|
idle_power_usage = 0.1 KILOWATTS
|
||||||
|
appearance_flags = PIXEL_SCALE
|
||||||
|
var/active = TRUE
|
||||||
|
var/charge_cooldown = 1 SECOND //time between it can fire at different targets
|
||||||
|
var/last_shot = 0
|
||||||
|
var/kill_range = 18
|
||||||
|
var/rotation_speed = 0.25 SECONDS //How quickly we turn to face threats
|
||||||
|
var/engaging = FALSE
|
||||||
|
var/id_tag = null
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/Initialize()
|
||||||
|
. = ..()
|
||||||
|
// TODO - Remove this bit once machines are converted to Initialize
|
||||||
|
if(ispath(circuit))
|
||||||
|
circuit = new circuit(src)
|
||||||
|
default_apply_parts()
|
||||||
|
update_icon()
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/get_description_interaction()
|
||||||
|
. = ..()
|
||||||
|
if(!id_tag)
|
||||||
|
. += "[desc_panel_image("multitool")]to set ident tag and connect to a mainframe."
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/update_icon()
|
||||||
|
if(!active || !id_tag || inoperable())
|
||||||
|
icon_state = "[initial(icon_state)]_off"
|
||||||
|
else
|
||||||
|
icon_state = initial(icon_state)
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/power_change()
|
||||||
|
var/old_stat = stat
|
||||||
|
..()
|
||||||
|
if(old_stat != stat)
|
||||||
|
update_icon()
|
||||||
|
|
||||||
|
// Find controller with the same tag on connected z levels (if any)
|
||||||
|
/obj/machinery/pointdefense/proc/get_controller()
|
||||||
|
if(!id_tag)
|
||||||
|
return null
|
||||||
|
var/list/connected_z_levels = GetConnectedZlevels(get_z(src))
|
||||||
|
for(var/thing in pointdefense_controllers)
|
||||||
|
var/obj/machinery/pointdefense_control/PDC = thing
|
||||||
|
if(PDC.id_tag == id_tag && (get_z(PDC) in connected_z_levels))
|
||||||
|
return PDC
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/attackby(var/obj/item/W, var/mob/user)
|
||||||
|
if(W?.is_multitool())
|
||||||
|
var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text
|
||||||
|
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, physical_state))
|
||||||
|
to_chat(user, "<span class='notice'>You register [src] with the [new_ident] network.</span>")
|
||||||
|
id_tag = new_ident
|
||||||
|
return
|
||||||
|
if(default_deconstruction_screwdriver(user, W))
|
||||||
|
return
|
||||||
|
if(default_deconstruction_crowbar(user, W))
|
||||||
|
return
|
||||||
|
if(default_part_replacement(user, W))
|
||||||
|
return
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
//Guns cannot shoot through hull or generally dense turfs.
|
||||||
|
/obj/machinery/pointdefense/proc/space_los(meteor)
|
||||||
|
for(var/turf/T in getline(src,meteor))
|
||||||
|
if(T.density)
|
||||||
|
return FALSE
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/proc/Shoot(var/weakref/target)
|
||||||
|
var/obj/effect/meteor/M = target.resolve()
|
||||||
|
if(!istype(M))
|
||||||
|
return
|
||||||
|
engaging = TRUE
|
||||||
|
var/Angle = round(Get_Angle(src,M))
|
||||||
|
var/matrix/rot_matrix = matrix()
|
||||||
|
rot_matrix.Turn(Angle)
|
||||||
|
addtimer(CALLBACK(src, .proc/finish_shot, target), rotation_speed)
|
||||||
|
animate(src, transform = rot_matrix, rotation_speed, easing = SINE_EASING)
|
||||||
|
|
||||||
|
set_dir(ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH)
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/proc/finish_shot(var/weakref/target)
|
||||||
|
//Cleanup from list
|
||||||
|
var/obj/machinery/pointdefense_control/PC = get_controller()
|
||||||
|
if(istype(PC))
|
||||||
|
PC.targets -= target
|
||||||
|
|
||||||
|
engaging = FALSE
|
||||||
|
last_shot = world.time
|
||||||
|
var/obj/effect/meteor/M = target.resolve()
|
||||||
|
if(!istype(M))
|
||||||
|
return
|
||||||
|
//We throw a laser but it doesnt have to hit for meteor to explode
|
||||||
|
var/obj/item/projectile/beam/pointdefense/beam = new(get_turf(src))
|
||||||
|
playsound(src, 'sound/weapons/mandalorian.ogg', 75, 1)
|
||||||
|
use_power_oneoff(idle_power_usage * 10)
|
||||||
|
beam.launch_projectile(target = M.loc, user = src)
|
||||||
|
|
||||||
|
M.make_debris()
|
||||||
|
qdel(M)
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/process()
|
||||||
|
..()
|
||||||
|
if(stat & (NOPOWER|BROKEN))
|
||||||
|
return
|
||||||
|
if(!active)
|
||||||
|
return
|
||||||
|
var/desiredir = ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH
|
||||||
|
if(dir != desiredir)
|
||||||
|
set_dir(desiredir)
|
||||||
|
if(LAZYLEN(GLOB.meteor_list) > 0)
|
||||||
|
find_and_shoot()
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/proc/find_and_shoot()
|
||||||
|
if(LAZYLEN(GLOB.meteor_list) == 0)
|
||||||
|
return
|
||||||
|
if(engaging || ((world.time - last_shot) < charge_cooldown))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/obj/machinery/pointdefense_control/PC = get_controller()
|
||||||
|
if(!istype(PC))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/list/connected_z_levels = GetConnectedZlevels(get_z(src))
|
||||||
|
for(var/obj/effect/meteor/M in GLOB.meteor_list)
|
||||||
|
var/already_targeted = FALSE
|
||||||
|
for(var/weakref/WR in PC.targets)
|
||||||
|
var/obj/effect/meteor/m = WR.resolve()
|
||||||
|
if(m == M)
|
||||||
|
already_targeted = TRUE
|
||||||
|
break
|
||||||
|
if(!istype(m))
|
||||||
|
PC.targets -= WR
|
||||||
|
|
||||||
|
if(already_targeted)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if(!(M.z in connected_z_levels))
|
||||||
|
continue
|
||||||
|
if(get_dist(M, src) > kill_range)
|
||||||
|
continue
|
||||||
|
if(!emagged && space_los(M))
|
||||||
|
var/weakref/target = weakref(M)
|
||||||
|
PC.targets += target
|
||||||
|
Shoot(target)
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/RefreshParts()
|
||||||
|
. = ..()
|
||||||
|
// Calculates an average rating of components that affect shooting rate
|
||||||
|
var/shootrate_divisor = total_component_rating_of_type(/obj/item/weapon/stock_parts/capacitor)
|
||||||
|
|
||||||
|
charge_cooldown = 2 SECONDS / (shootrate_divisor ? shootrate_divisor : 1)
|
||||||
|
|
||||||
|
//Calculate max shooting range
|
||||||
|
var/killrange_multiplier = total_component_rating_of_type(/obj/item/weapon/stock_parts/capacitor)
|
||||||
|
killrange_multiplier += 1.5 * total_component_rating_of_type(/obj/item/weapon/stock_parts/scanning_module)
|
||||||
|
|
||||||
|
kill_range = 10 + 4 * killrange_multiplier
|
||||||
|
|
||||||
|
var/rotation_divisor = total_component_rating_of_type(/obj/item/weapon/stock_parts/manipulator)
|
||||||
|
rotation_speed = 0.5 SECONDS / (rotation_divisor ? rotation_divisor : 1)
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/proc/Activate()
|
||||||
|
if(active)
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
playsound(src, 'sound/weapons/flash.ogg', 100, 0)
|
||||||
|
update_use_power(USE_POWER_IDLE)
|
||||||
|
active = TRUE
|
||||||
|
update_icon()
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/obj/machinery/pointdefense/proc/Deactivate()
|
||||||
|
if(!active)
|
||||||
|
return FALSE
|
||||||
|
playsound(src, 'sound/machines/apc_nopower.ogg', 50, 0)
|
||||||
|
update_use_power(USE_POWER_OFF)
|
||||||
|
active = FALSE
|
||||||
|
update_icon()
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
//
|
||||||
|
// Projectile Beam Definitions
|
||||||
|
//
|
||||||
|
|
||||||
|
/obj/item/projectile/beam/pointdefense
|
||||||
|
name = "point defense salvo"
|
||||||
|
icon_state = "laser"
|
||||||
|
damage = 15
|
||||||
|
damage_type = ELECTROCUTE //You should be safe inside a voidsuit
|
||||||
|
sharp = FALSE //"Wide" spectrum beam
|
||||||
|
light_color = COLOR_GOLD
|
||||||
|
|
||||||
|
muzzle_type = /obj/effect/projectile/muzzle/pointdefense
|
||||||
|
tracer_type = /obj/effect/projectile/tracer/pointdefense
|
||||||
|
impact_type = /obj/effect/projectile/impact/pointdefense
|
||||||
|
|
||||||
|
|
||||||
|
/obj/effect/projectile/tracer/pointdefense
|
||||||
|
icon_state = "beam_pointdef"
|
||||||
|
|
||||||
|
/obj/effect/projectile/muzzle/pointdefense
|
||||||
|
icon_state = "muzzle_pointdef"
|
||||||
|
|
||||||
|
/obj/effect/projectile/impact/pointdefense
|
||||||
|
icon_state = "impact_pointdef"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef T_BOARD
|
||||||
|
#error T_BOARD macro is not defined but we need it!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/obj/item/weapon/circuitboard/pointdefense
|
||||||
|
name = T_BOARD("point defense battery")
|
||||||
|
board_type = new /datum/frame/frame_types/machine
|
||||||
|
desc = "Control systems for a Kuiper pattern point defense battery. Aim away from vessel."
|
||||||
|
build_path = /obj/machinery/pointdefense
|
||||||
|
origin_tech = list(TECH_ENGINEERING = 3, TECH_COMBAT = 2)
|
||||||
|
req_components = list(
|
||||||
|
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser = 1,
|
||||||
|
/obj/item/weapon/stock_parts/manipulator = 2,
|
||||||
|
/obj/item/weapon/stock_parts/capacitor = 2,
|
||||||
|
)
|
||||||
|
|
||||||
|
/obj/item/weapon/circuitboard/pointdefense_control
|
||||||
|
name = T_BOARD("fire assist mainframe")
|
||||||
|
board_type = new /datum/frame/frame_types/machine
|
||||||
|
desc = "A control computer to synchronize point defense batteries."
|
||||||
|
build_path = /obj/machinery/pointdefense_control
|
||||||
|
origin_tech = list(TECH_ENGINEERING = 3, TECH_COMBAT = 2)
|
||||||
|
req_components = list()
|
||||||
@@ -621,6 +621,19 @@ CIRCUITS BELOW
|
|||||||
build_path = /obj/item/weapon/circuitboard/microwave/advanced
|
build_path = /obj/item/weapon/circuitboard/microwave/advanced
|
||||||
sort_string = "MAAAC"
|
sort_string = "MAAAC"
|
||||||
|
|
||||||
|
/datum/design/circuit/pointdefense
|
||||||
|
name = "point defense battery"
|
||||||
|
id = "pointdefense"
|
||||||
|
req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 3, TECH_COMBAT = 4)
|
||||||
|
build_path = /obj/item/weapon/circuitboard/pointdefense
|
||||||
|
sort_string = "OAABA"
|
||||||
|
|
||||||
|
/datum/design/circuit/pointdefense_control
|
||||||
|
name = "deluxe microwave"
|
||||||
|
id = "pointdefense_control"
|
||||||
|
req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_COMBAT = 2)
|
||||||
|
build_path = /obj/item/weapon/circuitboard/pointdefense_control
|
||||||
|
sort_string = "OAABB"
|
||||||
|
|
||||||
/* I have no idea how this was even running before, but it doesn't seem to be necessary.
|
/* I have no idea how this was even running before, but it doesn't seem to be necessary.
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
|
|||||||
BIN
icons/obj/pointdefense.dmi
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.1 KiB |
54
nano/templates/pointdefense_control.tmpl
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<h2>Fire Assist Mainframe: {{:data.id || "[no tag]"}}</h2>
|
||||||
|
{{if !(data.id)}}
|
||||||
|
<div class="notice">
|
||||||
|
<span class='bad'>This system has not been assigned an ident tag. Please contact your system administrator or conduct a manual update with a standard multitool.</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{for data.turrets}}
|
||||||
|
<h3>{{:value.id}}</h3>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelWide">
|
||||||
|
Battery status
|
||||||
|
</div>
|
||||||
|
<div class="itemContentMedium">
|
||||||
|
{{if value.active}}
|
||||||
|
<span class="fixedLeft good">Online</span> {{:helper.link('Shut down', null, {'toggle_active': value.ref})}}
|
||||||
|
{{else}}
|
||||||
|
<span class="fixedLeft average">Offline</span> {{:helper.link('Start up', null, {'toggle_active': value.ref})}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelWide">
|
||||||
|
Effective range
|
||||||
|
</div>
|
||||||
|
<div class="itemContentMedium">
|
||||||
|
{{:value.effective_range}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelWide">
|
||||||
|
Reaction wheel delay
|
||||||
|
</div>
|
||||||
|
<div class="itemContentMedium">
|
||||||
|
{{:value.reaction_wheel_delay}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabelWide">
|
||||||
|
Recharge time
|
||||||
|
</div>
|
||||||
|
<div class="itemContentMedium">
|
||||||
|
{{:value.recharge_time}}
|
||||||
|
</div>
|
||||||
|
{{empty}}
|
||||||
|
<div class="item">
|
||||||
|
<div class="itemLabel">
|
||||||
|
Error:
|
||||||
|
</div>
|
||||||
|
<div class="itemContent">
|
||||||
|
No weapon systems detected. Please check network connection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
{{/for}}
|
||||||
BIN
sound/machines/apc_nopower.ogg
Normal file
@@ -783,6 +783,7 @@
|
|||||||
#include "code\game\machinery\painter_vr.dm"
|
#include "code\game\machinery\painter_vr.dm"
|
||||||
#include "code\game\machinery\partslathe_vr.dm"
|
#include "code\game\machinery\partslathe_vr.dm"
|
||||||
#include "code\game\machinery\pda_multicaster.dm"
|
#include "code\game\machinery\pda_multicaster.dm"
|
||||||
|
#include "code\game\machinery\pointdefense.dm"
|
||||||
#include "code\game\machinery\portable_turret.dm"
|
#include "code\game\machinery\portable_turret.dm"
|
||||||
#include "code\game\machinery\portable_turret_vr.dm"
|
#include "code\game\machinery\portable_turret_vr.dm"
|
||||||
#include "code\game\machinery\recharger.dm"
|
#include "code\game\machinery\recharger.dm"
|
||||||
@@ -1208,6 +1209,7 @@
|
|||||||
#include "code\game\objects\items\weapons\circuitboards\machinery\recharge_station.dm"
|
#include "code\game\objects\items\weapons\circuitboards\machinery\recharge_station.dm"
|
||||||
#include "code\game\objects\items\weapons\circuitboards\machinery\research.dm"
|
#include "code\game\objects\items\weapons\circuitboards\machinery\research.dm"
|
||||||
#include "code\game\objects\items\weapons\circuitboards\machinery\shieldgen.dm"
|
#include "code\game\objects\items\weapons\circuitboards\machinery\shieldgen.dm"
|
||||||
|
#include "code\game\objects\items\weapons\circuitboards\machinery\ships.dm"
|
||||||
#include "code\game\objects\items\weapons\circuitboards\machinery\telecomms.dm"
|
#include "code\game\objects\items\weapons\circuitboards\machinery\telecomms.dm"
|
||||||
#include "code\game\objects\items\weapons\circuitboards\machinery\unary_atmos.dm"
|
#include "code\game\objects\items\weapons\circuitboards\machinery\unary_atmos.dm"
|
||||||
#include "code\game\objects\items\weapons\grenades\anti_photon_grenade.dm"
|
#include "code\game\objects\items\weapons\grenades\anti_photon_grenade.dm"
|
||||||
|
|||||||