diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm index 28a7431ec1..f295676402 100644 --- a/code/datums/supplypacks/engineering.dm +++ b/code/datums/supplypacks/engineering.dm @@ -77,13 +77,19 @@ containertype = /obj/structure/closet/crate/focalpoint containername = "advanced hull shield generator crate" -/datum/supply_pack/eng/pointdefense - name = "Point Defense Turret" - contains = list(/obj/machinery/porta_turret/pointdefense/orderable) - cost = 70 - containertype = /obj/structure/closet/crate/large/secure/heph - containername = "point defense crate" - access = access_security +/datum/supply_pack/eng/point_defense_cannon_circuit + name = "Point Defense Turret Circuit" + contains = list(/obj/item/weapon/circuitboard/pointdefense = 2) + cost = 20 + containertype = /obj/structure/closet/crate/heph + containername = "point defense turret circuit crate" + +/datum/supply_pack/eng/point_defense_control_circuit + name = "Point Defense Controller Circuit" + contains = list(/obj/item/weapon/circuitboard/pointdefense_control = 1) + cost = 30 + containertype = /obj/structure/closet/crate/heph + containername = "point defense mainframe circuit crate" /datum/supply_pack/eng/electrical name = "Electrical maintenance crate" diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index a6ceb219c8..5f3b8d542a 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -109,13 +109,13 @@ desc = "You should probably run instead of gawking at this." icon = 'icons/obj/meteor.dmi' icon_state = "small" - density = 1 - anchored = 1 + density = TRUE + anchored = TRUE var/hits = 4 var/hitpwr = 2 //Level of ex_act to be called on hit. var/dest pass_flags = PASSTABLE - var/heavy = 0 + var/heavy = FALSE var/z_original var/meteordrop = /obj/item/weapon/ore/iron @@ -147,7 +147,11 @@ get_hit() /obj/effect/meteor/Destroy() +<<<<<<< HEAD walk(src,0) //this cancels the walk_towards() proc +======= + walk(src,FALSE) //this cancels the walk_towards() proc +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting GLOB.meteor_list -= src return ..() @@ -162,10 +166,10 @@ ram_turf(get_turf(A)) get_hit() else - die(0) + die(FALSE) /obj/effect/meteor/CanPass(atom/movable/mover, turf/target) - return istype(mover, /obj/effect/meteor) ? 1 : ..() + return istype(mover, /obj/effect/meteor) ? TRUE : ..() /obj/effect/meteor/proc/ram_turf(var/turf/T) //first bust whatever is in the turf @@ -190,9 +194,9 @@ /obj/effect/meteor/proc/get_hit() hits-- if(hits <= 0) - die(1) + die(TRUE) -/obj/effect/meteor/proc/die(var/explode = 1) +/obj/effect/meteor/proc/die(var/explode = TRUE) make_debris() meteor_effect(explode) qdel(src) @@ -209,16 +213,13 @@ /obj/effect/meteor/bullet_act(var/obj/item/projectile/Proj) if(Proj.excavation_amount) get_hit() - if(!QDELETED(src)) - wall_power -= Proj.excavation_amount + Proj.damage + (Proj.hitscan * 25) // Instant-impact projectiles are inherently better at dealing with meteors. - wall_power = max(1, wall_power) - if(wall_power < Proj.excavation_amount) - if(prob(min(90, 100 - Proj.damage))) - die(TRUE) - else - die(FALSE) - return + if(!QDELETED(src)) + wall_power -= Proj.excavation_amount + Proj.damage + (Proj.hitscan * 25) // Instant-impact projectiles are inherently better at dealing with meteors. + + if(wall_power <= 0) + die(FALSE) // If you kill the meteor, then it dies. + return return /obj/effect/meteor/proc/make_debris() diff --git a/code/game/machinery/pointdefense.dm b/code/game/machinery/pointdefense.dm index 51f48c416b..54912ec94d 100644 --- a/code/game/machinery/pointdefense.dm +++ b/code/game/machinery/pointdefense.dm @@ -4,17 +4,29 @@ // GLOBAL_LIST_BOILERPLATE(pointdefense_controllers, /obj/machinery/pointdefense_control) +<<<<<<< HEAD GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) +======= +GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting /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." +<<<<<<< HEAD +======= + description_info = "To connect the mainframe to turrets, use a multitool to set the ident tag to that of the turrets." +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting 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 +<<<<<<< HEAD +======= + var/ui_template = "pointdefense_control.tmpl" +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting var/id_tag = null /obj/machinery/pointdefense_control/Initialize(mapload) @@ -36,6 +48,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) if(!id_tag) . += "[desc_panel_image("multitool")]to set ident tag" +<<<<<<< HEAD /obj/machinery/pointdefense_control/tgui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) @@ -72,11 +85,59 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) /obj/machinery/pointdefense_control/tgui_data(mob/user) var/list/data = list() data["id"] = id_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, "[PD] is not within control range.") + 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 +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting var/list/turrets = list() if(id_tag) var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) for(var/i = 1 to LAZYLEN(pointdefense_turrets)) +<<<<<<< HEAD var/obj/machinery/power/pointdefense/PD = pointdefense_turrets[i] +======= + var/obj/machinery/pointdefense/PD = pointdefense_turrets[i] +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting if(!(PD.id_tag == id_tag && get_z(PD) in connected_z_levels)) continue var/list/turret = list() @@ -95,7 +156,11 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) /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 +<<<<<<< HEAD if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state)) +======= + if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, physical_state)) +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting // Check for duplicate controllers with this ID for(var/thing in pointdefense_controllers) var/obj/machinery/pointdefense_control/PC = thing @@ -117,32 +182,52 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) // The acutal point defense battery // +<<<<<<< HEAD /obj/machinery/power/pointdefense name = "\improper point defense battery" icon = 'icons/obj/pointdefense.dmi' icon_state = "pointdefense2" 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." +======= +/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. Use a multitool to set the ident tag." +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting density = TRUE anchored = TRUE circuit = /obj/item/weapon/circuitboard/pointdefense idle_power_usage = 0.1 KILOWATTS +<<<<<<< HEAD active_power_usage = 1 KILOWATTS +======= +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting 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 +<<<<<<< HEAD var/engaging = FALSE var/id_tag = null /obj/machinery/power/pointdefense/Initialize() +======= + var/weakref/engaging = null // The meteor we're shooting at + var/id_tag = null + +/obj/machinery/pointdefense/Initialize() +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting . = ..() // TODO - Remove this bit once machines are converted to Initialize if(ispath(circuit)) circuit = new circuit(src) default_apply_parts() +<<<<<<< HEAD if(anchored) connect_to_network() update_icon() @@ -156,16 +241,26 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) . += "It is connected to a power cable below." /obj/machinery/power/pointdefense/get_description_interaction() +======= + update_icon() + +/obj/machinery/pointdefense/get_description_interaction() +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting . = ..() if(!id_tag) . += "[desc_panel_image("multitool")]to set ident tag and connect to a mainframe." +<<<<<<< HEAD /obj/machinery/power/pointdefense/update_icon() +======= +/obj/machinery/pointdefense/update_icon() +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting if(!active || !id_tag || inoperable()) icon_state = "[initial(icon_state)]_off" else icon_state = initial(icon_state) +<<<<<<< HEAD /obj/machinery/power/pointdefense/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/W, var/time) if((. = ..())) src.transform = null // Reset rotation if we're anchored/unanchored @@ -184,11 +279,15 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) /obj/machinery/power/pointdefense/power_change() if(powernet) return // We don't care, we are cable powered anyway +======= +/obj/machinery/pointdefense/power_change() +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting var/old_stat = stat ..() if(old_stat != stat) update_icon() +<<<<<<< HEAD // Decide where to get the power to fire from /obj/machinery/power/pointdefense/use_power_oneoff(var/amount, var/chan = -1) if(powernet) @@ -200,6 +299,10 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) // Find controller with the same tag on connected z levels (if any) /obj/machinery/power/pointdefense/proc/get_controller() +======= +// Find controller with the same tag on connected z levels (if any) +/obj/machinery/pointdefense/proc/get_controller() +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting if(!id_tag) return null var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) @@ -208,10 +311,17 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) if(PDC.id_tag == id_tag && (get_z(PDC) in connected_z_levels)) return PDC +<<<<<<< HEAD /obj/machinery/power/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, GLOB.tgui_physical_state)) +======= +/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)) +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting to_chat(user, "You register [src] with the [new_ident] network.") id_tag = new_ident return @@ -221,22 +331,38 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) return if(default_part_replacement(user, W)) return +<<<<<<< HEAD if(default_unfasten_wrench(user, W, 40)) return return ..() //Guns cannot shoot through hull or generally dense turfs. /obj/machinery/power/pointdefense/proc/space_los(meteor) +======= + return ..() + +//Guns cannot shoot through hull or generally dense turfs. +/obj/machinery/pointdefense/proc/space_los(meteor) +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting for(var/turf/T in getline(src,meteor)) if(T.density) return FALSE return TRUE +<<<<<<< HEAD /obj/machinery/power/pointdefense/proc/Shoot(var/weakref/target) var/obj/effect/meteor/M = target.resolve() if(!istype(M)) return engaging = TRUE +======= +/obj/machinery/pointdefense/proc/Shoot(var/weakref/target) + var/obj/effect/meteor/M = target.resolve() + if(!istype(M)) + engaging = null + return + engaging = target +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting var/Angle = round(Get_Angle(src,M)) var/matrix/rot_matrix = matrix() rot_matrix.Turn(Angle) @@ -245,6 +371,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) set_dir(ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH) +<<<<<<< HEAD /obj/machinery/power/pointdefense/proc/finish_shot(var/weakref/target) //Cleanup from list var/obj/machinery/pointdefense_control/PC = get_controller() @@ -252,10 +379,19 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) PC.targets -= target engaging = FALSE +======= +/obj/machinery/pointdefense/proc/finish_shot(var/weakref/target) + + var/obj/machinery/pointdefense_control/PC = get_controller() + engaging = null + PC.targets -= target + +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting last_shot = world.time var/obj/effect/meteor/M = target.resolve() if(!istype(M)) return +<<<<<<< HEAD if(use_power_oneoff(active_power_usage) < active_power_usage) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) @@ -287,12 +423,39 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) /obj/machinery/power/pointdefense/proc/find_and_shoot() if(LAZYLEN(GLOB.meteor_list) == 0) 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) + +/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() + // There ARE meteors to shoot + if(LAZYLEN(GLOB.meteor_list) == 0) + return + // We can shoot +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting if(engaging || ((world.time - last_shot) < charge_cooldown)) return var/obj/machinery/pointdefense_control/PC = get_controller() if(!istype(PC)) return +<<<<<<< HEAD var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) for(var/obj/effect/meteor/M in GLOB.meteor_list) @@ -319,6 +482,47 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) return /obj/machinery/power/pointdefense/RefreshParts() +======= + + // Compile list of known targets + var/list/existing_targets = list() + for(var/weakref/WR in PC.targets) + var/obj/effect/meteor/M = WR.resolve() + existing_targets += M + + // First, try and acquire new targets + var/list/potential_targets = GLOB.meteor_list.Copy() - existing_targets + for(var/obj/effect/meteor/M in potential_targets) + if(targeting_check(M)) + var/weakref/target = weakref(M) + PC.targets += target + engaging = target + Shoot(target) + return + + // Then, focus fire on existing targets + for(var/obj/effect/meteor/M in existing_targets) + if(targeting_check(M)) + var/weakref/target = weakref(M) + engaging = target + Shoot(target) + return + +/obj/machinery/pointdefense/proc/targeting_check(var/obj/effect/meteor/M) + // Target in range + var/list/connected_z_levels = GetConnectedZlevels(get_z(src)) + if(!(M.z in connected_z_levels)) + return FALSE + if(get_dist(M, src) > kill_range) + return FALSE + // If we can shoot it, then shoot + if(emagged || !space_los(M)) + return FALSE + + return TRUE + +/obj/machinery/pointdefense/RefreshParts() +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting . = ..() // Calculates an average rating of components that affect shooting rate var/shootrate_divisor = total_component_rating_of_type(/obj/item/weapon/stock_parts/capacitor) @@ -334,7 +538,11 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) var/rotation_divisor = total_component_rating_of_type(/obj/item/weapon/stock_parts/manipulator) rotation_speed = 0.5 SECONDS / (rotation_divisor ? rotation_divisor : 1) +<<<<<<< HEAD /obj/machinery/power/pointdefense/proc/Activate() +======= +/obj/machinery/pointdefense/proc/Activate() +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting if(active) return FALSE @@ -344,7 +552,11 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) update_icon() return TRUE +<<<<<<< HEAD /obj/machinery/power/pointdefense/proc/Deactivate() +======= +/obj/machinery/pointdefense/proc/Deactivate() +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting if(!active) return FALSE playsound(src, 'sound/machines/apc_nopower.ogg', 50, 0) @@ -352,6 +564,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) active = FALSE update_icon() return TRUE +<<<<<<< HEAD // // Projectile Beam Definitions @@ -381,3 +594,5 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense) /obj/effect/projectile/impact/pointdefense icon = 'icons/obj/projectiles_vr.dmi' icon_state = "impact_pointdef" +======= +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 8e9e6da8f7..259a52797f 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -74,7 +74,6 @@ var/check_anomalies = TRUE //checks if it can shoot at unidentified lifeforms (ie xenos) var/check_synth = FALSE //if active, will shoot at anything not an AI or cyborg var/check_all = FALSE //If active, will fire on anything, including synthetics. - var/fire_at_movement = FALSE // If active, will fire on the most recent thing to move in range, as soon as possible. var/ailock = FALSE // AI cannot use this var/check_down = FALSE //If active, will shoot to kill when lethals are also on var/faction = null //if set, will not fire at people in the same faction for any reason. @@ -96,8 +95,6 @@ var/timeout = 10 // When a turret pops up, then finds nothing to shoot at, this number decrements until 0, when it pops down. var/can_salvage = TRUE // If false, salvaging doesn't give you anything. - var/stay_up = FALSE // If true, the turret will remain open while it is powered. - /obj/machinery/porta_turret/crescent req_one_access = list(access_cent_specops) enabled = FALSE @@ -279,31 +276,6 @@ ) return data -/obj/machinery/porta_turret/pointdefense - name = "point-defense turret" - turret_type = "core" - desc = "A basic ship-mounted rock-breaker." - description_info = "This turret is capable of blasting incoming meteors into gravel, but it is very limited in range." - - installation = /obj/item/weapon/gun/energy/mininglaser - - check_arrest = FALSE - check_records = FALSE - check_weapons = FALSE - check_access = FALSE - check_anomalies = FALSE - check_synth = FALSE - check_all = FALSE - fire_at_movement = TRUE - stay_up = TRUE - ailock = FALSE - check_down = FALSE - -/obj/machinery/porta_turret/pointdefense/orderable - enabled = FALSE - anchored = FALSE - locked = FALSE - /obj/machinery/porta_turret/Initialize() //Sets up a spark system spark_system = new /datum/effect/effect/system/spark_spread @@ -350,8 +322,11 @@ var/obj/item/projectile/P = initial(E.projectile_type) //var/obj/item/ammo_casing/shottype = E.projectile_type +<<<<<<< HEAD //GLOB.moved_event.register_global(src, /obj/machinery/porta_turret/proc/point_defense) //VOREStation Removal +======= +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting projectile = P lethal_projectile = projectile shot_sound = initial(P.fire_sound) @@ -407,14 +382,6 @@ lethal_shot_sound = 'sound/weapons/eluger.ogg' shot_sound = 'sound/weapons/Taser.ogg' - if(/obj/item/weapon/gun/energy/mininglaser) - lethal_icon_color = "green" - lethal_projectile = /obj/item/projectile/beam/mininglaser - lethal_shot_sound = 'sound/weapons/eluger.ogg' - icon_color = "red" - projectile = /obj/item/projectile/beam/weaklaser - shot_sound = 'sound/weapons/Laser.ogg' - /obj/machinery/porta_turret/proc/isLocked(mob/user) if(locked && !issilicon(user)) to_chat(user, "Controls locked.") @@ -444,7 +411,41 @@ tgui_interact(user) /obj/machinery/porta_turret/attack_hand(mob/user) +<<<<<<< HEAD tgui_interact(user) +======= + if(isLocked(user)) + return + + ui_interact(user) + +/obj/machinery/porta_turret/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + data["access"] = !isLocked(user) + data["locked"] = locked + data["enabled"] = enabled + data["is_lethal"] = 1 + data["lethal"] = lethal + + if(data["access"]) + var/settings[0] + settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth) + settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons) + settings[++settings.len] = list("category" = "Check Security Records", "setting" = "check_records", "value" = check_records) + settings[++settings.len] = list("category" = "Check Arrest Status", "setting" = "check_arrest", "value" = check_arrest) + settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access) + settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies) + settings[++settings.len] = list("category" = "Neutralize All Entities", "setting" = "check_all", "value" = check_all) + settings[++settings.len] = list("category" = "Neutralize Downed Entities", "setting" = "check_down", "value" = check_down) + data["settings"] = settings + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting /obj/machinery/porta_turret/proc/HasController() var/area/A = get_area(src) @@ -482,6 +483,7 @@ /obj/machinery/porta_turret/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) if(..()) +<<<<<<< HEAD return TRUE if(isLocked(usr)) return TRUE @@ -511,6 +513,34 @@ check_all = !check_all if("authdown") check_down = !check_down +======= + return 1 + + if(href_list["command"] && href_list["value"]) + var/value = text2num(href_list["value"]) + if(href_list["command"] == "enable") + enabled = value + else if(href_list["command"] == "lethal") + lethal = value + else if(href_list["command"] == "check_synth") + check_synth = value + else if(href_list["command"] == "check_weapons") + check_weapons = value + else if(href_list["command"] == "check_records") + check_records = value + else if(href_list["command"] == "check_arrest") + check_arrest = value + else if(href_list["command"] == "check_access") + check_access = value + else if(href_list["command"] == "check_anomalies") + check_anomalies = value + else if(href_list["command"] == "check_all") + check_all = value + else if(href_list["command"] == "check_down") + check_down = value + + return 1 +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting /obj/machinery/porta_turret/power_change() if(powered()) @@ -712,10 +742,6 @@ popDown() return - if(stay_up) - timeout = 10 - popUp() - var/list/targets = list() //list of primary targets var/list/secondarytargets = list() //targets that are least important @@ -738,7 +764,7 @@ if(!tryToShootAt(targets)) if(!tryToShootAt(secondarytargets)) // if no valid targets, go for secondary targets timeout-- - if(timeout <= 0 && !stay_up) + if(timeout <= 0) spawn() popDown() // no valid targets, close the cover @@ -746,14 +772,6 @@ use_power(20000) health = min(health+1, maxhealth) // 1HP for 20kJ -// We're expecting the first arg to be a target, for this we don't care about previous and next turfs. -/obj/machinery/porta_turret/proc/point_defense(var/atom/movable/Targ) - if((stat & (NOPOWER|BROKEN)) || !fire_at_movement) // Are we even able or supposed to fire at non-moving targets? - return - - if((isliving(Targ) && assess_living(Targ)) || ((istype(Targ, /obj/item) || istype(Targ, /obj/effect/meteor)) && Targ.invisibility < INVISIBILITY_LEVEL_ONE && Targ in view(7,src))) // Is the target a living thing, if so, is it a valid target? Or if it's not living, is it in sight? - target(Targ) // Yes? Blast it. - /obj/machinery/porta_turret/proc/assess_and_assign(var/mob/living/L, var/list/targets, var/list/secondarytargets) switch(assess_living(L)) if(TURRET_PRIORITY_TARGET) @@ -780,10 +798,10 @@ if(L.stat == DEAD && !emagged) //if the perp is dead, no need to bother really return TURRET_NOT_TARGET //move onto next potential victim! - if(get_dist(src, get_turf(L)) > 7) //if it's too far away, why bother? + if(get_dist(src, L) > 7) //if it's too far away, why bother? return TURRET_NOT_TARGET - if(!(L in check_trajectory(get_turf(L), src))) //check if we have true line of sight + if(!(L in check_trajectory(L, src))) //check if we have true line of sight return TURRET_NOT_TARGET if(emagged) // If emagged not even the dead get a rest @@ -890,9 +908,8 @@ last_target = target spawn() popUp() //pop the turret up if it's not already up. - if(dir != get_dir(src, target)) - set_dir(get_dir(src, target)) //even if you can't shoot, follow the target - playsound(src, 'sound/machines/turrets/turret_rotate.ogg', 100, 1) // Play rotating sound + set_dir(get_dir(src, target)) //even if you can't shoot, follow the target + playsound(src, 'sound/machines/turrets/turret_rotate.ogg', 100, 1) // Play rotating sound spawn() shootAt(target) return 1 @@ -956,9 +973,6 @@ var/check_weapons var/check_anomalies var/check_all - var/check_down - var/fire_at_movement - var/stay_up var/ailock /obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC) @@ -974,9 +988,6 @@ check_weapons = TC.check_weapons check_anomalies = TC.check_anomalies check_all = TC.check_all - check_down = TC.check_down - fire_at_movement = TC.fire_at_movement - stay_up = TC.stay_up ailock = TC.ailock power_change() diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm index 7f5a1d8e56..83a24fbbde 100644 --- a/code/game/machinery/turret_control.dm +++ b/code/game/machinery/turret_control.dm @@ -19,6 +19,7 @@ var/locked = TRUE var/area/control_area //can be area name, path or nothing. +<<<<<<< HEAD var/targetting_is_configurable = TRUE // if false, you cannot change who this turret attacks via its UI var/check_arrest = TRUE //checks if the perp is set to arrest var/check_records = TRUE //checks if a security record exists at all @@ -33,6 +34,16 @@ var/ailock = FALSE //Silicons cannot use this var/syndicate = FALSE +======= + var/check_arrest = 1 //checks if the perp is set to arrest + var/check_records = 1 //checks if a security record exists at all + var/check_weapons = 0 //checks if it can shoot people that have a weapon they aren't authorized to have + var/check_access = 1 //if this is active, the turret shoots everything that does not meet the access requirements + var/check_anomalies = 1 //checks if it can shoot at unidentified lifeforms (ie xenos) + var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg + var/check_all = 0 //If active, will shoot at anything. + var/ailock = 0 //Silicons cannot use this +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting req_access = list(access_ai_upload) @@ -124,8 +135,34 @@ /obj/machinery/turretid/attack_hand(mob/user as mob) tgui_interact(user) +<<<<<<< HEAD /obj/machinery/turretid/tgui_interact(mob/user, datum/tgui/ui = null) ui = SStgui.try_update_ui(user, src, ui) +======= + ui_interact(user) + +/obj/machinery/turretid/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + data["access"] = !isLocked(user) + data["locked"] = locked + data["enabled"] = enabled + data["is_lethal"] = 1 + data["lethal"] = lethal + + if(data["access"]) + var/settings[0] + settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth) + settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons) + settings[++settings.len] = list("category" = "Check Security Records", "setting" = "check_records", "value" = check_records) + settings[++settings.len] = list("category" = "Check Arrest Status", "setting" = "check_arrest", "value" = check_arrest) + settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access) + settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies) + settings[++settings.len] = list("category" = "Neutralize All Entities", "setting" = "check_all", "value" = check_all) + + data["settings"] = settings + + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting if(!ui) ui = new(user, src, "PortableTurret", name) // 500, 400 ui.open() @@ -153,9 +190,34 @@ /obj/machinery/turretid/tgui_act(action, params) if(..()) +<<<<<<< HEAD return if(isLocked(usr)) return +======= + return 1 + + if(href_list["command"] && href_list["value"]) + var/value = text2num(href_list["value"]) + if(href_list["command"] == "enable") + enabled = value + else if(href_list["command"] == "lethal") + lethal = value + else if(href_list["command"] == "check_synth") + check_synth = value + else if(href_list["command"] == "check_weapons") + check_weapons = value + else if(href_list["command"] == "check_records") + check_records = value + else if(href_list["command"] == "check_arrest") + check_arrest = value + else if(href_list["command"] == "check_access") + check_access = value + else if(href_list["command"] == "check_anomalies") + check_anomalies = value + else if(href_list["command"] == "check_all") + check_all = value +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting . = TRUE switch(action) @@ -196,9 +258,6 @@ TC.check_weapons = check_weapons TC.check_anomalies = check_anomalies TC.check_all = check_all - TC.check_down = check_down - TC.stay_up = stay_up - TC.fire_at_movement = fire_at_movement TC.ailock = ailock if(istype(control_area)) diff --git a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm index e48606a2ac..0b7225aab2 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm @@ -80,6 +80,7 @@ light_power = 3 light_color = "#3300ff" +<<<<<<< HEAD //VOREStation edit: medigun /obj/effect/projectile/impact/medigun icon = 'icons/obj/projectiles_vr.dmi' @@ -87,4 +88,8 @@ light_range = 2 light_power = 0.5 light_color = "#80F5FF" -//VOREStation edit ends \ No newline at end of file +//VOREStation edit ends +======= +/obj/effect/projectile/impact/pointdefense + icon_state = "impact_pointdef" +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting diff --git a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm index a5c70aab2c..5325b63262 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm @@ -92,6 +92,7 @@ light_power = 3 light_color = "#3300ff" +<<<<<<< HEAD //VOREStation edit: medigun /obj/effect/projectile/muzzle/medigun icon = 'icons/obj/projectiles_vr.dmi' @@ -99,4 +100,8 @@ light_range = 2 light_power = 0.5 light_color = "#80F5FF" -//VOREStation edit ends \ No newline at end of file +//VOREStation edit ends +======= +/obj/effect/projectile/muzzle/pointdefense + icon_state = "muzzle_pointdef" +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting diff --git a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm index 4326bc536d..ee55a87b9b 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm @@ -121,6 +121,7 @@ light_power = 0.5 light_color = "#f6f2b6" +<<<<<<< HEAD //VOREStation edit: medigun /obj/effect/projectile/tracer/medigun icon = 'icons/obj/projectiles_vr.dmi' @@ -129,3 +130,7 @@ light_power = 0.5 light_color = "#80F5FF" //VOREStation edit ends +======= +/obj/effect/projectile/tracer/pointdefense + icon_state = "beam_pointdef" +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting diff --git a/code/game/objects/items/weapons/circuitboards/machinery/ships.dm b/code/game/objects/items/weapons/circuitboards/machinery/ships.dm index b71e7ce37b..ff5c25c2ec 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/ships.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/ships.dm @@ -6,8 +6,13 @@ 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." +<<<<<<< HEAD build_path = /obj/machinery/power/pointdefense origin_tech = list(TECH_ENGINEERING = 3, TECH_COMBAT = 2, TECH_POWER = 2) +======= + build_path = /obj/machinery/pointdefense + origin_tech = list(TECH_ENGINEERING = 3, TECH_COMBAT = 2) +>>>>>>> 031f8a7... Merge pull request #7919 from Atermonera/point_defense_targeting req_components = list( /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser = 1, /obj/item/weapon/stock_parts/manipulator = 2, diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 1612e1cab3..12f2cf09e6 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -279,3 +279,22 @@ /obj/item/projectile/beam/shock/weak damage = 5 agony = 10 + + +// +// 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 + + excavation_amount = 200 // Good at shooting rocks + + muzzle_type = /obj/effect/projectile/muzzle/pointdefense + tracer_type = /obj/effect/projectile/tracer/pointdefense + impact_type = /obj/effect/projectile/impact/pointdefense diff --git a/code/modules/research/designs/circuits/circuits.dm b/code/modules/research/designs/circuits/circuits.dm index d24644ce7b..87b86fe1fe 100644 --- a/code/modules/research/designs/circuits/circuits.dm +++ b/code/modules/research/designs/circuits/circuits.dm @@ -632,6 +632,19 @@ CIRCUITS BELOW build_path = /obj/item/weapon/circuitboard/microwave/advanced sort_string = "HACAA" +/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 = "point defense control" + 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" /datum/design/circuit/shield_generator name = "shield generator" diff --git a/icons/obj/projectiles_impact.dmi b/icons/obj/projectiles_impact.dmi index 9d63ee10fc..de1c614b53 100644 Binary files a/icons/obj/projectiles_impact.dmi and b/icons/obj/projectiles_impact.dmi differ diff --git a/icons/obj/projectiles_muzzle.dmi b/icons/obj/projectiles_muzzle.dmi index 86a8b747d8..254f33e950 100644 Binary files a/icons/obj/projectiles_muzzle.dmi and b/icons/obj/projectiles_muzzle.dmi differ diff --git a/icons/obj/projectiles_tracer.dmi b/icons/obj/projectiles_tracer.dmi index a633df6735..8a71334aae 100644 Binary files a/icons/obj/projectiles_tracer.dmi and b/icons/obj/projectiles_tracer.dmi differ diff --git a/nano/templates/pointdefense_control.tmpl b/nano/templates/pointdefense_control.tmpl new file mode 100644 index 0000000000..19f85d3dba --- /dev/null +++ b/nano/templates/pointdefense_control.tmpl @@ -0,0 +1,54 @@ +