diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm index c35d048f54..0529f5aedd 100644 --- a/code/datums/supplypacks/engineering.dm +++ b/code/datums/supplypacks/engineering.dm @@ -77,6 +77,20 @@ containertype = /obj/structure/closet/crate/focalpoint containername = "advanced hull shield generator crate" +/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" contains = list( diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index 0b0b8d014c..6b88e45765 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -13,7 +13,7 @@ /obj/effect/meteor/big=3, /obj/effect/meteor/flaming=1, /obj/effect/meteor/irradiated=3 - ) + ) //for threatening meteor event /var/list/meteors_threatening = list( @@ -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,7 @@ get_hit() /obj/effect/meteor/Destroy() - walk(src,0) //this cancels the walk_towards() proc + walk(src,FALSE) //this cancels the walk_towards() proc GLOB.meteor_list -= src return ..() @@ -162,10 +162,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 +190,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) @@ -206,6 +206,18 @@ return ..() +/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. + + if(wall_power <= 0) + die(FALSE) // If you kill the meteor, then it dies. + return + return + /obj/effect/meteor/proc/make_debris() for(var/throws = dropamt, throws > 0, throws--) var/obj/item/O = new meteordrop(get_turf(src)) @@ -330,4 +342,4 @@ /obj/effect/meteor/tunguska/Bump() ..() if(prob(20)) - explosion(src.loc,2,4,6,8) + explosion(src.loc,2,4,6,8) \ No newline at end of file diff --git a/code/game/machinery/pointdefense.dm b/code/game/machinery/pointdefense.dm index 2a98271836..a05abd0c94 100644 --- a/code/game/machinery/pointdefense.dm +++ b/code/game/machinery/pointdefense.dm @@ -10,6 +10,7 @@ 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." + description_info = "To connect the mainframe to turrets, use a multitool to set the ident tag to that of the turrets." icon = 'icons/obj/pointdefense.dmi' icon_state = "control" power_channel = EQUIP // CHOMPStation Edit Starts @@ -125,7 +126,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) 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." + 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." density = TRUE anchored = TRUE circuit = /obj/item/weapon/circuitboard/pointdefense @@ -137,7 +138,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) var/last_shot = 0 var/kill_range = 18 var/rotation_speed = 4.5 SECONDS //How quickly we turn to face threats - var/engaging = FALSE + var/weakref/engaging = null // The meteor we're shooting at var/id_tag = null /obj/machinery/pointdefense/Initialize() @@ -146,17 +147,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) if(ispath(circuit)) circuit = new circuit(src) default_apply_parts() - // if(anchored) - // connect_to_network() update_icon() - var/image/I = image(icon, icon_state = "[icon_state]_under") - I.appearance_flags |= RESET_TRANSFORM - underlays += I - -// /obj/machinery/pointdefense/examine(mob/user) -// . = ..() -// if(powernet) -// . += "It is connected to a power cable below." /obj/machinery/pointdefense/get_description_interaction() . = ..() @@ -169,38 +160,12 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) else icon_state = initial(icon_state) -/obj/machinery/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 - -////////// This machine is willing to take power from cables OR APCs. Handle NOPOWER stat specially here! //////// -/* -/obj/machinery/pointdefense/connect_to_network() - if((. = ..())) - stat &= ~NOPOWER // We now ignore APC power - update_icon() - -/obj/machinery/pointdefense/disconnect_from_network() - if((. = ..())) - power_change() // We're back on APC power. - /obj/machinery/pointdefense/power_change() - if(powernet) - return // We don't care, we are cable powered anyway var/old_stat = stat ..() if(old_stat != stat) update_icon() -// Decide where to get the power to fire from -/obj/machinery/pointdefense/use_power_oneoff(var/amount, var/chan = -1) - if(powernet) - return draw_power(amount) - else if(powered(chan)) - use_power(amount, chan) - return amount - return 0 */ - // Find controller with the same tag on connected z levels (if any) /obj/machinery/pointdefense/proc/get_controller() if(!id_tag) @@ -223,8 +188,6 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) return if(default_part_replacement(user, W)) return - if(default_unfasten_wrench(user, W, 40)) - return return ..() //Guns cannot shoot through hull or generally dense turfs. @@ -237,8 +200,9 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) /obj/machinery/pointdefense/proc/Shoot(var/weakref/target) var/obj/effect/meteor/M = target.resolve() if(!istype(M)) + engaging = null return - engaging = TRUE + engaging = target var/Angle = round(Get_Angle(src,M)) var/matrix/rot_matrix = matrix() rot_matrix.Turn(Angle) @@ -248,47 +212,38 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) 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 = null + PC.targets -= target - engaging = FALSE last_shot = world.time var/obj/effect/meteor/M = target.resolve() if(!istype(M)) return - /*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) - s.start() - visible_message("[src] sputters as browns out while attempting to fire.") - flick(src, "[initial(icon_state)]_off") - 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(!anchored || stat & (BROKEN)) + if(stat & (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 if(engaging || ((world.time - last_shot) < charge_cooldown)) return @@ -296,29 +251,42 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) if(!istype(PC) || !PC.powered(EQUIP)) 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 + // 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 - 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)) + // 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() . = ..() @@ -353,33 +321,4 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense) //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 = 'icons/obj/projectiles_vr.dmi' - icon_state = "beam_pointdef" - -/obj/effect/projectile/muzzle/pointdefense - icon = 'icons/obj/projectiles_vr.dmi' - icon_state = "muzzle_pointdef" - -/obj/effect/projectile/impact/pointdefense - icon = 'icons/obj/projectiles_vr.dmi' - icon_state = "impact_pointdef" + return TRUE \ No newline at end of file diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 81e04792c1..cc71d5983c 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -903,7 +903,6 @@ var/check_weapons var/check_anomalies var/check_all - var/check_down var/ailock /obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC) @@ -919,7 +918,6 @@ check_weapons = TC.check_weapons check_anomalies = TC.check_anomalies check_all = TC.check_all - check_down = TC.check_down ailock = TC.ailock power_change() diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm index 6e684974aa..cd0ebf2d71 100644 --- a/code/game/machinery/turret_control.dm +++ b/code/game/machinery/turret_control.dm @@ -194,7 +194,6 @@ TC.check_weapons = check_weapons TC.check_anomalies = check_anomalies TC.check_all = check_all - TC.check_down = check_down 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 6c99d70482..adecdbe1c0 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm @@ -94,4 +94,6 @@ 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" \ No newline at end of file diff --git a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm index 9b3ff9e03c..44240eb487 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm @@ -106,4 +106,6 @@ 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" \ No newline at end of file diff --git a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm index 1f2d72282a..9f05cc30ca 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm @@ -134,3 +134,5 @@ light_power = 0.5 light_color = "#80F5FF" //VOREStation edit ends +/obj/effect/projectile/tracer/pointdefense + icon_state = "beam_pointdef" \ No newline at end of file diff --git a/code/game/objects/items/weapons/circuitboards/machinery/ships.dm b/code/game/objects/items/weapons/circuitboards/machinery/ships.dm index c502deb338..dd37bc2519 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/ships.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/ships.dm @@ -7,7 +7,7 @@ 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, TECH_POWER = 2) + 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, diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index d363bc7ccf..15f8d24a5b 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -331,6 +331,26 @@ 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 + + /obj/item/projectile/beam/precursor //CHOMPedit added Precursor beam name = "precursor beam" icon_state = "alien beam" diff --git a/code/modules/research/designs/circuits/circuits.dm b/code/modules/research/designs/circuits/circuits.dm index f3a7e396ab..933cd26091 100644 --- a/code/modules/research/designs/circuits/circuits.dm +++ b/code/modules/research/designs/circuits/circuits.dm @@ -676,6 +676,20 @@ 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" id = "shield_generator"