diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index 16ec7cea1413..7a66ef0fc805 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -101,7 +101,7 @@ SUBSYSTEM_DEF(mapping) var/turf/shadow_loc = locate(round((GLOB.maps_data.pulsar_size)/2 - (GLOB.maps_data.pulsar_size)/4), round((GLOB.maps_data.pulsar_size)/2 + (GLOB.maps_data.pulsar_size)/4), GLOB.maps_data.pulsar_z) var/obj/effect/pulsar_ship/ship = new /obj/effect/pulsar_ship(satellite_loc) - var/newshadow = new /obj/effect/pulsar_ship/shadow(shadow_loc) + var/newshadow = new /obj/effect/pulsar_ship_shadow(shadow_loc) ship.shadow = newshadow if (!GLOB.maps_data.pulsar_star) diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 36933f8386b6..f8d8c815bb78 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -384,6 +384,7 @@ area/space/atmosalert() icon_state = "engineering" // area_light_color = COLOR_LIGHTING_SCI_BRIGHT requires_power = 0 + dynamic_lighting = FALSE holomap_color = HOLOMAP_AREACOLOR_ENGINEERING ambience = list('sound/ambience/technoambient1.ogg','sound/ambience/technoambient2.ogg', 'sound/ambience/technoambient3.ogg','sound/ambience/technoambient4.ogg', diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 9b3c9583601d..e24fad4e7f24 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -153,6 +153,23 @@ proc/fragment_explosion_angled(atom/epicenter, turf/origin , projectile_type, pr pew_thingie.firer = epicenter pew_thingie.launch(pick(hittable_turfs)) +//Generic proc for spread of any projectile type. +proc/projectile_explosion(var/turf/epicenter, var/range, var/p_type, var/p_amount = 10, var/list/p_damage = list()) + if(!isturf(epicenter)) + epicenter = get_turf(epicenter) + if(!epicenter || !p_type) + return + var/list/target_turfs = getcircle(epicenter, range) + while(p_amount) + sleep(0) + var/obj/item/projectile/P = new p_type(epicenter) + if(length(p_damage)) + P.damage_types = p_damage + + P.shot_from = epicenter + + P.launch(pick(target_turfs)) + p_amount-- diff --git a/code/modules/pulsar_engine/pulsar_consoles.dm b/code/modules/pulsar_engine/pulsar_consoles.dm index 72c569ecd399..4b3094e466e2 100644 --- a/code/modules/pulsar_engine/pulsar_consoles.dm +++ b/code/modules/pulsar_engine/pulsar_consoles.dm @@ -1,4 +1,6 @@ -/obj/machinery/pulsar +#define PULSAR_100_POWER 400000 + +/obj/machinery/pulsar //Not meant to be destroyed, snowflake object for control, lots of things hold refs to it so it would harddel name = "pulsar starmap" icon = 'icons/obj/computer.dmi' icon_state = "computer" @@ -14,7 +16,7 @@ /obj/machinery/pulsar/Initialize(mapload, d) linked = GLOB.maps_data.pulsar_star - ship = locate(/obj/effect/pulsar_ship) in world + ship = locate(/obj/effect/pulsar_ship) in get_area(linked) if(ship) RegisterSignal(ship, COMSIG_MOVABLE_MOVED, .proc/onShipMoved) ..() @@ -32,6 +34,10 @@ /obj/machinery/pulsar/Process() SSnano.update_uis(src) + if(shield_power < get_required_shielding()) + ship.try_overcharge(TRUE) + else + ship.try_overcharge(FALSE) /obj/machinery/pulsar/power_change() ..() @@ -94,6 +100,7 @@ tank.air_contents.remove(thrust_cost) var/newdir = text2num(href_list["move"]) ship.try_move(newdir, TRUE) + else if(href_list["scan_fuel"]) scan_for_fuel() @@ -101,6 +108,7 @@ var/target_level = input(usr, "Set shielding power", "Shield control", 50) as num if(target_level < 100) shield_power = max(0 , target_level) + SSnano.update_uis(src) ..() @@ -132,6 +140,77 @@ tank?.connected_console = src SSnano.update_uis(src) +/obj/machinery/power/pulsar_power_bridge //Only holds ref to the console and its area, used to get power from it, or disconnect the ship. + name = "pulsar power bridge" + icon = 'icons/obj/computer.dmi' + icon_state = "computer" + density = TRUE + anchored = TRUE + layer = BELOW_OBJ_LAYER + var/obj/machinery/pulsar/pulsar_console + var/area/console_area + +/obj/machinery/power/pulsar_power_bridge/Initialize(mapload, d) + connect_to_network() + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/power/pulsar_power_bridge/LateInitialize() + . = ..() + pulsar_console = locate() in world //I can get away with it once, right? + if(pulsar_console) + console_area = get_area(pulsar_console) //Area stored so reconnections are cheaper. + +/obj/machinery/power/pulsar_power_bridge/Process() + if(powernet && pulsar_console) + add_avail(PULSAR_100_POWER * pulsar_console.get_effective_power_porduced()) + . = ..() + +/obj/machinery/power/pulsar_power_bridge/power_change() + ..() + SSnano.update_uis(src) + +/obj/machinery/power/pulsar_power_bridge/attack_hand(mob/user) + . = ..() + ui_interact(user) + +/obj/machinery/power/pulsar_power_bridge/ui_interact(mob/user, ui_key, datum/nanoui/ui, force_open, datum/nanoui/master_ui, datum/topic_state/state) + . = ..() + if(stat & (BROKEN|NOPOWER)) return + if(user.stat || user.restrained()) return + + var/list/data = ui_data() + + ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "pulsar_power_bridge.tmpl", name, 550, 400) + ui.set_initial_data(data) + ui.open() + +/obj/machinery/power/pulsar_power_bridge/ui_data() + var/list/data = list() + data["pulsar_connected"] = FALSE + if(pulsar_console) + data["pulsar_connected"] = TRUE + data["power_percentage"] = pulsar_console.get_effective_power_porduced() + data["power_produced"] = PULSAR_100_POWER * pulsar_console.get_effective_power_porduced() + + return data + +/obj/machinery/power/pulsar_power_bridge/Topic(href, href_list, datum/topic_state/state) + if(href_list["disconnect"]) + pulsar_console = null + else if(href_list["reconnect"]) + pulsar_console = locate() in console_area + SSnano.update_uis(src) + +/obj/machinery/power/pulsar_power_bridge/examine(mob/user, distance, infix, suffix) + ..(user) + to_chat(user, "\The [src] appears to be producing [PULSAR_100_POWER * pulsar_console.get_effective_power_porduced()] W.") + +/obj/machinery/power/pulsar_power_bridge/Destroy() + pulsar_console = null + . = ..() + /obj/structure/pulsar_fuel_tank name = "pulsar fuel tank" desc = "A massive fuel tank refialable by smaller gas tanks." @@ -186,3 +265,5 @@ to_chat(user, "Fuel: [round(air_contents.get_total_moles())]/100") if(round(air_contents.get_total_moles()) >= 100) to_chat(user, SPAN_DANGER("It looks like its about to burst!")) + +#undef PULSAR_100_POWER diff --git a/code/modules/pulsar_engine/pulsar_events.dm b/code/modules/pulsar_engine/pulsar_events.dm index cd8fe9e93f28..f707475fb116 100644 --- a/code/modules/pulsar_engine/pulsar_events.dm +++ b/code/modules/pulsar_engine/pulsar_events.dm @@ -1,7 +1,7 @@ //Pulsar events /datum/pulsar_event - var/name = "parent of all pulsar events" + //Base parent for pulsar events /datum/pulsar_event/proc/check_tile(tile) var/turf/T = tile @@ -10,8 +10,9 @@ var/list/banned_objects = list(/obj/effect/pulsar) banned_objects += typesof(/obj/effect/pulsar_beam) banned_objects += typesof(/obj/effect/pulsar_ship) - for(var/O in T) - if(O in banned_objects) + banned_objects += typesof(/obj/effect/portal) + for(var/atom/A in range(1, T)) + if(A.type in banned_objects) return FALSE return TRUE @@ -27,12 +28,11 @@ return /datum/pulsar_event/pulsar_portals - name = "pulsar portals" /datum/pulsar_event/pulsar_portals/on_trigger() var/turf/portal_1_turf = get_valid_tile() - var/turf/portal_2_turf = get_valid_tile() var/obj/effect/portal/perfect/portal_1 = new /obj/effect/portal/perfect(portal_1_turf) + var/turf/portal_2_turf = get_valid_tile() var/obj/effect/portal/perfect/portal_2 = new /obj/effect/portal/perfect(portal_2_turf) portal_1.set_target(portal_2_turf) portal_2.set_target(portal_1_turf) @@ -85,5 +85,53 @@ . = ..() for(var/datum/weather/rad_storm/R in SSweather.processing) R.wind_down() - command_announcement.Announce("The sattelite has passed the radiation beams. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert") + command_announcement.Announce("The pulsar sattelite has passed the radiation beams. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert") revoke_maint_all_access() + +#define PULAR_RIFT_COOLDOWN 3 MINUTES +/datum/event/pulsar_overcharge + startWhen = 5 + announceWhen = 1 + endWhen = INFINITY // YEA. Again. + var/last_rift_spawn = - PULAR_RIFT_COOLDOWN + var/list/pulsar_rifts = list() + +/datum/event/pulsar_overcharge/announce() + command_announcement.Announce("The pulsar sattelite has been overloaded with power, expect excess energy to be dumped onto your vessel, ебать.", "Technomancer Pulsar Monitor") + +/datum/event/pulsar_overcharge/tick() + . = ..() + if(world.time > last_rift_spawn + PULAR_RIFT_COOLDOWN) + spwawn_new_rift_wave(rand(4,6)) + last_rift_spawn = world.time + command_announcement.Announce("Another wave of energy has been dumbed on your vessel.", "Technomancer Pulsar Monitor") + + for(var/obj/effect/rift in pulsar_rifts) + projectile_explosion(get_turf(rift), 10, /obj/item/projectile/beam/emitter, rand(5, 10), list(BURN = 100)) + + +/datum/event/pulsar_overcharge/proc/spwawn_new_rift_wave(amount) + for(var/i in 1 to amount) + var/area/A = random_ship_area(FALSE, TRUE, TRUE) + var/turf/T = A.random_space() + if(!T) + //We somehow failed to find a turf, decrement i so we get another go + i-- + continue + var/obj/effect/pulsar_rift/p = new(T) + pulsar_rifts |= p + + +/datum/event/pulsar_overcharge/end() + for(var/obj/effect/pulsar_rift/p in pulsar_rifts) + pulsar_rifts -= p + qdel(p) + command_announcement.Announce("Pulsar sattelite energy levels stabilized.", "Technomancer Pulsar Monitor") + . = ..() + +/obj/effect/pulsar_rift + name = "Pulsar rift" + icon = 'icons/obj/objects.dmi' + icon_state = "wormhole" + anchored = TRUE + diff --git a/code/modules/pulsar_engine/pulsar_map.dm b/code/modules/pulsar_engine/pulsar_map.dm index 797cc55cbeaa..dfd276193839 100644 --- a/code/modules/pulsar_engine/pulsar_map.dm +++ b/code/modules/pulsar_engine/pulsar_map.dm @@ -33,25 +33,28 @@ desc = "The orbit target for the satellite" icon = 'icons/obj/overmap.dmi' icon_state = "ihs_capital_g" - var/obj/effect/pulsar_ship/shadow - var/do_decay = TRUE + var/obj/effect/shadow var/decay_timer = 5 MINUTES var/fuel = 100 var/fuel_movement_cost = 5 var/crash_timer_id + var/overcharge_timer_id var/obj/item/device/radio/radio var/datum/event/pulsar_rad_storm/storm + var/datum/event/pulsar_overcharge/overcharge //Should have made it a subsystem by now, huh? /obj/effect/pulsar_ship/New() . = ..() - if(do_decay) - addtimer(CALLBACK(src, .proc/decay_orbit), decay_timer) - radio = new /obj/item/device/radio{channels=list("Engineering")}(src) + addtimer(CALLBACK(src, .proc/decay_orbit), decay_timer) + radio = new /obj/item/device/radio{channels=list("Engineering")}(src) /obj/effect/pulsar_ship/Destroy() . = ..() - if(radio) - qdel(radio) + qdel(radio) + storm.endWhen = 1 + storm = null + overcharge.endWhen = 1 + overcharge = null /obj/effect/pulsar_ship/proc/decay_orbit() var/movedir = pick(NORTH, SOUTH, EAST, WEST) @@ -73,8 +76,8 @@ if(O.type == /obj/effect/pulsar_beam) beam_collision = TRUE if(!crash_timer_id) - radio.autosay("WARNING: COLLISION WITH RADIATION BEAMS IMMINENT! ETA: 3 MINUTES!", "Pulsar Monitor", "Engineering") - crash_timer_id = addtimer(CALLBACK(src, .proc/crash_into_beam), 3 MINUTES, TIMER_STOPPABLE) + radio.autosay("WARNING: COLLISION WITH RADIATION BEAMS IMMINENT! ETA: 3 MINUTES!", "Pulsar Monitor", "Engineering", TRUE) + crash_timer_id = addtimer(CALLBACK(src, .proc/crash_into_beam), 15 SECONDS, TIMER_STOPPABLE) if(!beam_collision) if(crash_timer_id) deltimer(crash_timer_id) @@ -89,6 +92,26 @@ storm = new() storm.Initialize() -/obj/effect/pulsar_ship/shadow - do_decay = FALSE +/obj/effect/pulsar_ship/proc/try_overcharge(start = TRUE) + if(start) + if(!overcharge_timer_id) + radio.autosay("WARNING: PULSAR OVERCHARGE IMMINENT! ETA: 3 MINUTES!", "Pulsar Monitor", "Engineering", TRUE) + overcharge_timer_id = addtimer(CALLBACK(src, .proc/overcharge), 15 SECONDS, TIMER_STOPPABLE) + else + if(overcharge_timer_id) + deltimer(overcharge_timer_id) + overcharge_timer_id = null + if(overcharge) + overcharge.endWhen = 1 + overcharge = null + +/obj/effect/pulsar_ship/proc/overcharge() + overcharge = new() + overcharge.Initialize() + +/obj/effect/pulsar_ship_shadow + name = "Technomancer satellite orbit" + desc = "The orbit target for the satellite" + icon = 'icons/obj/overmap.dmi' + icon_state = "ihs_capital_g" alpha = 255 * 0.5 diff --git a/maps/pulsar/pulsar.dmm b/maps/pulsar/pulsar.dmm index 5a8f17f331e3..21a4bf88ca40 100644 --- a/maps/pulsar/pulsar.dmm +++ b/maps/pulsar/pulsar.dmm @@ -610,6 +610,12 @@ }, /turf/simulated/floor/tiled/techmaint, /area/outpost/pulsar/maintenance) +"xa" = ( +/obj/effect/map_effect/portal/line/side_a{ + dir = 8 + }, +/turf/simulated/floor/reinforced, +/area/outpost/pulsar) "xl" = ( /obj/structure/table/rack, /obj/spawner/pack/tech_loot/low_chance, @@ -1044,6 +1050,10 @@ }, /turf/simulated/floor/tiled/white, /area/outpost/pulsar/maintenance) +"LI" = ( +/obj/structure/pulsar_fuel_tank, +/turf/simulated/wall/r_wall, +/area/outpost/pulsar) "LW" = ( /obj/machinery/door/airlock/maintenance_engineering{ icon_state = "door_locked"; @@ -1093,6 +1103,17 @@ /obj/spawner/booze/low_chance, /turf/simulated/floor/tiled/steel/orangecorner, /area/outpost/pulsar/maintenance) +"Nd" = ( +/obj/effect/map_effect/portal/master/side_a{ + portal_id = "pulsar"; + dir = 8 + }, +/turf/simulated/floor/reinforced, +/area/outpost/pulsar) +"Nf" = ( +/obj/machinery/pulsar, +/turf/simulated/floor/tiled/dark/gray_perforated, +/area/outpost/pulsar) "Nh" = ( /obj/machinery/atmospherics/unary/engine{ dir = 4 @@ -1169,6 +1190,10 @@ "PC" = ( /turf/simulated/floor/reinforced, /area/outpost/pulsar) +"PM" = ( +/obj/structure/pulsar_fuel_tank, +/turf/simulated/floor/tiled/dark, +/area/outpost/pulsar) "PR" = ( /obj/structure/bed/chair{ dir = 4 @@ -20238,7 +20263,7 @@ aa OB OB oe -oe +Nf oe OB OB @@ -20846,7 +20871,7 @@ jC Ue kT Pw -Yf +PM ad HA HA @@ -21047,7 +21072,7 @@ ad ad ad Yy -ad +LI ad ad aa @@ -23266,11 +23291,11 @@ bM aa aa ad -PC -PC -PC -PC -PC +Nd +xa +xa +xa +xa ad aa aa diff --git a/nano/templates/pulsar_power_bridge.tmpl b/nano/templates/pulsar_power_bridge.tmpl new file mode 100644 index 000000000000..e2f76a9aa0d6 --- /dev/null +++ b/nano/templates/pulsar_power_bridge.tmpl @@ -0,0 +1,18 @@ + +

Pulsar power bridge

+{{if data.pulsar_connected}} +
+
+ Power Produced: +
+
+ {{:helper.displayBar(data.power_percentage, 0, 100, 'good', data.power_produced + '% Watts')}} + {{:helper.link('disconnect sattelite', 'radiation', { 'disconnect' : 1 }, null, null)}} +
+
+{{else}} +

NO POWER

+ {{:helper.link('reconnect sattelite', 'radiation', { 'reconnect' : 1 }, null, null)}} +{{/if}} \ No newline at end of file