diff --git a/code/__DEFINES/wires.dm b/code/__DEFINES/wires.dm index 9b0883173a9e..c2b807b8aa8b 100644 --- a/code/__DEFINES/wires.dm +++ b/code/__DEFINES/wires.dm @@ -100,6 +100,7 @@ #define WIRE_FIRE_DETECT "Automatic Detection" #define WIRE_FIRE_TRIGGER "Alarm Trigger" #define WIRE_FIRE_RESET "Alarm Reset" +#define WIRE_DISCHARGE "Discharge" // OCULIS EDIT ADDITION // Wire states for the AI #define AI_WIRE_NORMAL 0 diff --git a/code/_onclick/hud/parallax/random_layer.dm b/code/_onclick/hud/parallax/random_layer.dm index dad43cd8d1b5..bb72bfb69c73 100644 --- a/code/_onclick/hud/parallax/random_layer.dm +++ b/code/_onclick/hud/parallax/random_layer.dm @@ -24,11 +24,13 @@ /// Gassy background with a few random colors /atom/movable/screen/parallax_layer/random/space_gas + /* // OCULIS EDIT REMOVAL START //IRIS EDIT START icon = 'modular_iris/master_files/icons/effects/electrobox.dmi' icon_state = "lightning" speed = 0.5 //IRIS EDIT END + */ // OCULIS EDIT REMOVAL END /// The colors we can be var/possible_colors = list(COLOR_STRONG_VIOLET, COLOR_VIOLET, COLOR_LIGHT_PINK, COLOR_MOSTLY_PURE_PINK, COLOR_AMETHYST, COLOR_OCULIS_LOGO, COLOR_PURPLE) //OCULIS EDIT diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 660e345ec49a..1a7609a3b242 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -243,6 +243,7 @@ SUBSYSTEM_DEF(ticker) //Configure mode and assign player to antagonists var/can_continue = FALSE can_continue = SSdynamic.select_roundstart_antagonists() //Choose antagonists + SSeidolon_storm.initialize_storm_intensity() // OCULIS EDIT ADDITION - EIDOLON_STORM CHECK_TICK SEND_GLOBAL_SIGNAL(COMSIG_GLOB_PRE_JOBS_ASSIGNED, src) can_continue = can_continue && SSjob.divide_occupations() //Distribute jobs diff --git a/modular_oculis/modules/storm/code/anchor/anchor_computer.dm b/modular_oculis/modules/storm/code/anchor/anchor_computer.dm new file mode 100644 index 000000000000..62d0e32a25f2 --- /dev/null +++ b/modular_oculis/modules/storm/code/anchor/anchor_computer.dm @@ -0,0 +1,69 @@ +/obj/item/circuitboard/computer/redspace_anchor_control + name = "Redspace Anchor Control" + greyscale_colors = CIRCUIT_COLOR_COMMAND + build_path = /obj/machinery/computer/redspace_anchor_computer + +/obj/machinery/computer/redspace_anchor_computer + name = "redspace anchor control computer" + desc = "Used to control the redspace anchor." + icon_screen = "comm" + circuit = /obj/item/circuitboard/computer/redspace_anchor_control + var/obj/machinery/redspace_anchor/connected_anchor = null + +/obj/machinery/computer/redspace_anchor_computer/Initialize(mapload, obj/item/circuitboard/C) + . = ..() + for(var/obj/machinery/redspace_anchor/anchor as anything in SSmachines.get_machines_by_type(/obj/machinery/redspace_anchor)) + if(anchor.z == z) + connected_anchor = anchor + update_appearance() + +/obj/machinery/computer/redspace_anchor_computer/update_overlays() + if(connected_anchor?.breaker) + icon_screen = "comm" + else + icon_screen = "syndishuttle" + . = ..() + +/obj/machinery/computer/redspace_anchor_computer/ui_status(mob/user, datum/ui_state/state) + if(HAS_SILICON_ACCESS(user) && connected_anchor.ai_disabled) + to_chat(user, span_info("AI control has been disabled.")) + else if(!connected_anchor.shorted) + return ..() + return UI_CLOSE + +/obj/machinery/computer/redspace_anchor_computer/ui_interact(mob/user, datum/tgui/ui) + . = ..() + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RedspaceAnchor", name) + ui.open() + +/obj/machinery/computer/redspace_anchor_computer/ui_data(mob/user) + var/list/data = list() + data["breaker"] = connected_anchor.breaker + data["charge_count"] = connected_anchor.charge_count + data["charging_state"] = connected_anchor.charging_state + data["on"] = connected_anchor.on + data["operational"] = (connected_anchor.machine_stat & BROKEN) ? FALSE : TRUE + data["violetspace_energy"] = connected_anchor.violetspace_energy + return data + +/obj/machinery/computer/redspace_anchor_computer/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + switch(action) + if("gentoggle") + connected_anchor.breaker = !connected_anchor.breaker + investigate_log("was toggled [connected_anchor.breaker ? "ON" : "OFF"] by [key_name(usr)].", INVESTIGATE_ENGINE) + if(connected_anchor.violetspace_energy) + connected_anchor.trigger_unsafe_discharge() + investigate_log("was overloaded by remaining violetspace energy.", INVESTIGATE_ENGINE) + connected_anchor.set_power() + . = TRUE + if("discharge_violetspace") + if(connected_anchor.violetspace_energy && connected_anchor.can_discharge) + investigate_log("has discharged violetspace energy by [key_name(usr)].", INVESTIGATE_ENGINE) + connected_anchor.trigger_safe_discharge() + . = TRUE diff --git a/modular_oculis/modules/storm/code/anchor/redspace_anchor.dm b/modular_oculis/modules/storm/code/anchor/redspace_anchor.dm new file mode 100644 index 000000000000..10094bafefd4 --- /dev/null +++ b/modular_oculis/modules/storm/code/anchor/redspace_anchor.dm @@ -0,0 +1,278 @@ +#define POWER_IDLE 0 +#define POWER_UP 1 +#define POWER_DOWN 2 + +/obj/machinery/redspace_anchor + name = "redspace anchor" + icon = 'modular_oculis/modules/storm/icons/redspace_anchor.dmi' + icon_state = "anchor_off" + interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + + /* + * Yes, I know this doesn't use BASE_MACHINE_IDLE_CONSUMPTION at all, + * and this is purelly done so that the code is readable without pulling out a calculator + * to make sure these values are right. + */ + use_power = IDLE_POWER_USE + idle_power_usage = (6 MEGA WATTS) // Lotta fucking power to keep the storm at bay. + + // 3x3 offset by one row + pixel_x = -32 + pixel_y = -32 + bound_height = 96 + bound_width = 96 + bound_x = -32 + bound_y = -32 + density = TRUE + move_resist = INFINITY + + /// Whether the redspace anchor is currently active. + var/on = TRUE + /// If the main breaker is on/off, to enable/disable the anchor. + var/breaker = TRUE + /// If the power cable is cut or not. + var/shorted = FALSE + /// If a silicon can interact with it. + var/ai_disabled = FALSE + /// If the anchor will produce an alarm when changing states. + var/alarm_disabled = FALSE + /// If the anchor can safely discharge its redspace energy. + var/can_discharge = TRUE + /// If the generator is idle, charging, or down. + var/charging_state = POWER_IDLE + /// How much charge the redspace anchor has, goes down when breaker is shut, and shuts down at 0. + var/charge_count = 100 + + /// The overlay currently used. + var/current_overlay = null + + /// Audio for when the redspace anchor is on + var/datum/looping_sound/redspace_anchor/soundloop + + /// How much excess violetspace energy the redspace anchor has, which can cause it to fail once it reaches 100. + var/violetspace_energy = 0 + +/obj/machinery/redspace_anchor/Initialize(mapload) + . = ..() + SSeidolon_storm.register_anchor(src) + set_wires(new /datum/wires/redspace_anchor(src)) + soundloop = new(src, start_immediately = FALSE) + if(on) + add_overlay("activated") + +/obj/machinery/redspace_anchor/examine(mob/user) + if(HAS_TRAIT(user, TRAIT_MINDSHIELD)) + desc = "The most important machine on the station. You feel more... Stable, near it." + return ..() + desc = "The most important machine on the station. \n[span_danger("Looking directly at it gives you a headache.")]" + return ..() + +/obj/machinery/redspace_anchor/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE) + return FALSE + +/obj/machinery/redspace_anchor/ex_act(severity, target) + if(severity >= EXPLODE_DEVASTATE) // Very sturdy. + set_broken() + return TRUE + return FALSE + +/obj/machinery/redspace_anchor/blob_act(obj/structure/blob/B) + if(prob(20)) + set_broken() + +/obj/machinery/redspace_anchor/zap_act(power, zap_flags) + . = ..() + if(zap_flags & ZAP_MACHINE_EXPLOSIVE) + qdel(src) //like the singulo, tesla deletes it. stops it from exploding over and over + +// You aren't allowed to move. +/obj/machinery/redspace_anchor/Move() + . = ..() + qdel(src) + +/obj/machinery/redspace_anchor/proc/set_broken() + atom_break() + update_appearance() + +/obj/machinery/redspace_anchor/proc/set_fix() + set_machine_stat(machine_stat & ~BROKEN) + update_appearance() + +/obj/machinery/redspace_anchor/update_icon_state() + . = ..() + if(on) + icon_state = "anchor_on" + else + icon_state = "anchor_off" + +/obj/machinery/redspace_anchor/screwdriver_act(mob/living/user, obj/item/tool) + if(machine_stat & BROKEN) + return + tool.play_tool_sound(src) + toggle_panel_open() + to_chat(user, span_notice("The wires have been [panel_open ? "exposed" : "unexposed"].")) + update_appearance() + return TRUE + +// Wire interactions +/obj/machinery/redspace_anchor/proc/reset(wire) + switch(wire) + if(WIRE_POWER) + if(!wires.is_cut(WIRE_POWER)) + shorted = FALSE + set_power() + if(WIRE_AI) + if(!wires.is_cut(WIRE_AI)) + ai_disabled = FALSE + if(WIRE_ALARM) + if(!wires.is_cut(WIRE_ALARM)) + alarm_disabled = FALSE + if(WIRE_DISCHARGE) + update_appearance() + +/obj/machinery/redspace_anchor/power_change() + . = ..() + if(SSticker.current_state == GAME_STATE_PLAYING) + investigate_log("has [machine_stat & NOPOWER ? "lost" : "regained"] power.", INVESTIGATE_ENGINE) + set_power() + +// Set the charging state based on power/breaker. +/obj/machinery/redspace_anchor/proc/set_power() + var/new_state = FALSE + if(machine_stat & (NOPOWER|BROKEN) || !breaker || shorted) + new_state = FALSE + else if(breaker) + new_state = TRUE + + charging_state = new_state ? POWER_UP : POWER_DOWN // Startup sequence animation. + if(SSticker.current_state == GAME_STATE_PLAYING) + investigate_log("is now [charging_state == POWER_UP ? "charging" : "discharging"].", INVESTIGATE_ENGINE) + update_appearance() + +/obj/machinery/redspace_anchor/proc/enable() + charging_state = POWER_IDLE + on = TRUE + + //soundloop.start() + update_appearance() + + if(SSticker.current_state == GAME_STATE_PLAYING) + investigate_log("was brought online.", INVESTIGATE_ENGINE) + message_admins("The redspace anchor was brought online [ADMIN_VERBOSEJMP(src)]") + shake_everyone() + +/obj/machinery/redspace_anchor/proc/disable() + charging_state = POWER_IDLE + on = FALSE + + //soundloop.stop() + update_appearance() + + if(SSticker.current_state == GAME_STATE_PLAYING) + investigate_log("was brought offline.", INVESTIGATE_ENGINE) + message_admins("The redspace anchor was brought offline. [ADMIN_VERBOSEJMP(src)]") + shake_everyone() + +// Charge/Discharge and turn on/off when you reach 0/100 percent. +/obj/machinery/redspace_anchor/process() + if(machine_stat & BROKEN) + cut_overlays() + return + + var/overlay_state = null + switch(charge_count) + if(0 to 20) + overlay_state = null + if(21 to 40) + overlay_state = "startup" + if(41 to 60) + overlay_state = "idle" + if(61 to 80) + overlay_state = "activating" + if(81 to 100) + overlay_state = "activated" + + if(overlay_state != current_overlay) + cut_overlays() + if(overlay_state) + add_overlay(overlay_state) + current_overlay = overlay_state + + if(charging_state == POWER_IDLE) + return + if((charging_state == POWER_UP) && (charge_count >= 100)) + enable() + else if((charging_state == POWER_DOWN) && (charge_count <= 0)) + disable() + else + if(charging_state == POWER_UP) + charge_count += 2 + else if(charging_state == POWER_DOWN) + charge_count -= 2 + + for(var/mob/mobs as anything in GLOB.mob_list) + var/turf/mob_turf = get_turf(mobs) + if(!istype(mob_turf)) + continue + if(!is_valid_z_level(src, mob_turf)) + continue + if(mobs.client) + if((charge_count % 4 == 0 && prob(75)) && !alarm_disabled) // Let them know it is charging/discharging. + if(charging_state == POWER_UP) + mobs.playsound_local(mob_turf, 'sound/effects/magic/cosmic_expansion.ogg', 100, TRUE) + else + mobs.playsound_local(mob_turf, 'sound/effects/magic/swap.ogg', 100, TRUE) + if((charge_count <= 50) && (charging_state == POWER_DOWN) && prob(5)) + to_chat(mobs, span_bolddanger("You feel a foreign presence encroaching around you.")) + +/// Shake everyone on the z level to let them know that the anchor was enagaged/disengaged. +/obj/machinery/redspace_anchor/proc/shake_everyone() + var/turf/T = get_turf(src) + var/sound/alert_sound = sound('sound/effects/alert.ogg') + for(var/mob/mobs as anything in GLOB.mob_list) + var/turf/mob_turf = get_turf(mobs) + if(!istype(mob_turf)) + continue + if(!is_valid_z_level(T, mob_turf)) + continue + if(mobs.client) + shake_camera(mobs, 15, 1) + mobs.playsound_local(T, null, 100, 1, 0.5, sound_to_use = alert_sound) + if(!SSmapping.level_has_any_trait(z, ZTRAIT_STATION)) + return + if(on) + priority_announce("Redspace Anchor activated. Storm dissipation in progress.", "Redspace Anchor") + else + priority_announce("Warning: Redspace Anchor has been disabled. Storm encroaching on station perimeter.", "Redspace Anchor") + +/obj/machinery/redspace_anchor/proc/tick(intensity) + if((charging_state != POWER_IDLE) || !on) + return + violetspace_energy += (rand(1,5) * intensity) + if(violetspace_energy >= 100) + trigger_unsafe_discharge() + +/obj/machinery/redspace_anchor/proc/trigger_unsafe_discharge() + violetspace_energy = 0 + breaker = FALSE + set_power() + priority_announce( + text = "Redspace Anchor failure! Unsafe shutdown in progress!", + title = "Redspace Anchor", + sound = SSstation.announcer.get_rand_alert_sound(), + has_important_message = TRUE, + ) + +/obj/machinery/redspace_anchor/proc/trigger_safe_discharge() + violetspace_energy = 0 + priority_announce( + text = "Redspace Anchor safe discharge in progress.", + title = "Redspace Anchor", + sound = SSstation.announcer.get_rand_alert_sound(), + has_important_message = TRUE, + ) + +#undef POWER_IDLE +#undef POWER_UP +#undef POWER_DOWN diff --git a/modular_oculis/modules/storm/code/anchor/redspace_anchor_soundloop.dm b/modular_oculis/modules/storm/code/anchor/redspace_anchor_soundloop.dm new file mode 100644 index 000000000000..d75c4e5767d9 --- /dev/null +++ b/modular_oculis/modules/storm/code/anchor/redspace_anchor_soundloop.dm @@ -0,0 +1,6 @@ +/datum/looping_sound/redspace_anchor + mid_sounds = list('sound/machines/hypertorus/loops/hypertorus_nominal.ogg') + mid_length = 6 SECONDS + volume = 55 + extra_range = 15 + vary = TRUE diff --git a/modular_oculis/modules/storm/code/anchor/wires.dm b/modular_oculis/modules/storm/code/anchor/wires.dm new file mode 100644 index 000000000000..eea37514f107 --- /dev/null +++ b/modular_oculis/modules/storm/code/anchor/wires.dm @@ -0,0 +1,65 @@ +/datum/wires/redspace_anchor + holder_type = /obj/machinery/redspace_anchor + proper_name = "Redspace Anchor" + +/datum/wires/redspace_anchor/New(atom/holder) + wires = list( + WIRE_POWER, + WIRE_AI, + WIRE_ALARM, + WIRE_DISCHARGE, + ) + add_duds(13) // It's a complicated machine. It's gonna have lots of wires. + ..() + +/datum/wires/redspace_anchor/interactable(mob/user) + if(!..()) + return FALSE + return TRUE + +/datum/wires/redspace_anchor/get_status() + var/obj/machinery/redspace_anchor/A = holder + var/list/status = list() + status += "The short indicator is [A.shorted ? "lit" : "off"]." + status += "The AI connection light is [!A.ai_disabled ? "on" : "off"]." + status += "The alarm light is [!A.alarm_disabled ? "on" : "off"]." + return status + +/datum/wires/redspace_anchor/on_pulse(wire) + var/obj/machinery/redspace_anchor/anchor = holder + switch(wire) + if(WIRE_POWER) // Short out for a long time. + if(!anchor.shorted) + anchor.shorted = TRUE + anchor.update_appearance() + addtimer(CALLBACK(anchor, TYPE_PROC_REF(/obj/machinery/redspace_anchor, reset), wire), 2 MINUTES) + if(WIRE_AI) // Disable AI control for a while. + if(!anchor.ai_disabled) + anchor.ai_disabled = TRUE + addtimer(CALLBACK(anchor, TYPE_PROC_REF(/obj/machinery/redspace_anchor, reset), wire), 10 SECONDS) + if(WIRE_ALARM) + if(!anchor.alarm_disabled) + anchor.alarm_disabled = TRUE + addtimer(CALLBACK(anchor, TYPE_PROC_REF(/obj/machinery/redspace_anchor, reset), wire), 10 SECONDS) + anchor.update_appearance() + if(WIRE_DISCHARGE) + if(anchor.can_discharge && anchor.violetspace_energy) + anchor.trigger_safe_discharge() + +/datum/wires/redspace_anchor/on_cut(wire, mend, source) + var/obj/machinery/redspace_anchor/anchor = holder + switch(wire) + if(WIRE_POWER) + anchor.shorted = !mend + anchor.update_appearance() + if(WIRE_AI) + anchor.ai_disabled = mend // Enable/disable AI control. + if(WIRE_ALARM) + anchor.alarm_disabled = mend + if(WIRE_DISCHARGE) + anchor.can_discharge = mend + +/datum/wires/redspace_anchor/can_reveal_wires(mob/user) + if(HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + return TRUE + return ..() diff --git a/modular_oculis/modules/storm/code/storm/storm_layer.dm b/modular_oculis/modules/storm/code/storm/storm_layer.dm new file mode 100644 index 000000000000..c6bbe0c5f0cc --- /dev/null +++ b/modular_oculis/modules/storm/code/storm/storm_layer.dm @@ -0,0 +1,6 @@ +/atom/movable/screen/parallax_layer/random/space_gas/storm + parallax_color = list(1,0,0,0, 0,0,0,0, 0,0,2,0, 0,0,0,1, 0,0,0,0) //very vibrant purple + +/atom/movable/screen/parallax_layer/random/space_gas/storm/apply_global_effects() + . = ..() + set_base_starlight("#911855") diff --git a/modular_oculis/modules/storm/code/storm/storm_rulesets.dm b/modular_oculis/modules/storm/code/storm/storm_rulesets.dm new file mode 100644 index 000000000000..3f48ca526790 --- /dev/null +++ b/modular_oculis/modules/storm/code/storm/storm_rulesets.dm @@ -0,0 +1,46 @@ +#define STORM_INTENSITY_NONE 0 +#define STORM_INTENSITY_CALM 1 +#define STORM_INTENSITY_DRIZZLE 2 +#define STORM_INTENSITY_STORM 3 +#define STORM_INTENSITY_MONSOON 4 +#define STORM_INTENSITY_ADMIN 5 + +/datum/storm_ruleset + /// Which storm intensity this ruleset belongs to. See defines for values. + var/intensity = STORM_INTENSITY_NONE + /// Minimum population required for this ruleset to be selected at roundstart. + var/min_pop = 0 + /// How much time it takes between each storm cooldown. + var/storm_cooldown = 10 MINUTES + +/datum/storm_ruleset/calm + intensity = STORM_INTENSITY_CALM + min_pop = 0 + storm_cooldown = 10 MINUTES + +/datum/storm_ruleset/drizzle + intensity = STORM_INTENSITY_DRIZZLE + min_pop = 10 + storm_cooldown = 10 MINUTES + +/datum/storm_ruleset/storm + intensity = STORM_INTENSITY_STORM + min_pop = 15 + storm_cooldown = 5 MINUTES + +/datum/storm_ruleset/monsoon + intensity = STORM_INTENSITY_MONSOON + min_pop = 25 + storm_cooldown = 5 MINUTES + +/datum/storm_ruleset/admin + intensity = STORM_INTENSITY_ADMIN + min_pop = 999 + storm_cooldown = 10 MINUTES + +#undef STORM_INTENSITY_NONE +#undef STORM_INTENSITY_CALM +#undef STORM_INTENSITY_DRIZZLE +#undef STORM_INTENSITY_STORM +#undef STORM_INTENSITY_MONSOON +#undef STORM_INTENSITY_ADMIN diff --git a/modular_oculis/modules/storm/code/storm/storm_subsystem.dm b/modular_oculis/modules/storm/code/storm/storm_subsystem.dm new file mode 100644 index 000000000000..2fd59a2f45cd --- /dev/null +++ b/modular_oculis/modules/storm/code/storm/storm_subsystem.dm @@ -0,0 +1,54 @@ +PROCESSING_SUBSYSTEM_DEF(eidolon_storm) + name = "Eidolon Storm" + stat_tag = "ES" + ss_flags = SS_NO_INIT | SS_KEEP_TIMING + runlevels = RUNLEVEL_GAME + wait = 1 MINUTES + + COOLDOWN_DECLARE(eidolon_storm_cooldown) + /// Currently selected storem intensity. See defines for values. + var/datum/storm_ruleset/chosen_storm_ruleset = /datum/storm_ruleset + /// The station's redspace anchor. We shouldn't care for any other anchors in the game. + var/obj/machinery/redspace_anchor/station_anchor = null + +/datum/controller/subsystem/processing/eidolon_storm/proc/register_anchor(obj/machinery/redspace_anchor/anchor) + if(!SSmapping.level_has_any_trait(anchor.z, ZTRAIT_STATION)) // So that we can have decorative anchors on other z levels, like on castor. + return + if(station_anchor) // Incase some admin fucks up and spawns in a second anchor on the station z level. + return + station_anchor = anchor + +/datum/controller/subsystem/processing/eidolon_storm/proc/initialize_storm_intensity() + var/list/player_candidates = list() + for(var/mob/dead/new_player/player as anything in GLOB.new_player_list - SSjob.unassigned) + if(player.ready == PLAYER_READY_TO_PLAY && player.mind) + player_candidates += player + var/roundstart_population = length(player_candidates) + + var/list/possible_rulesets = list() + for(var/storm_ruleset as anything in subtypesof(/datum/storm_ruleset)) + var/datum/storm_ruleset/intensity_datum = new storm_ruleset() + if(roundstart_population < intensity_datum.min_pop) + qdel(intensity_datum) + continue + possible_rulesets += intensity_datum + chosen_storm_ruleset = pick(possible_rulesets) + + log_dynamic("Selected intensity: [chosen_storm_ruleset.intensity]") + log_dynamic("- Roundstart population: [roundstart_population]") + SSblackbox.record_feedback( + "associative", + "storm_intensity", + 1, + list( + "server_name" = CONFIG_GET(string/serversqlname), + "intensity" = chosen_storm_ruleset.intensity, + "player_count" = roundstart_population, + ), + ) + +/datum/controller/subsystem/processing/eidolon_storm/fire(resumed = FALSE) + if(!COOLDOWN_FINISHED(src, eidolon_storm_cooldown)) + return + COOLDOWN_START(src, eidolon_storm_cooldown, (chosen_storm_ruleset.storm_cooldown)) + station_anchor?.tick(chosen_storm_ruleset.intensity) diff --git a/modular_oculis/modules/storm/icons/redspace_anchor.dmi b/modular_oculis/modules/storm/icons/redspace_anchor.dmi new file mode 100644 index 000000000000..cdb2ab65852d Binary files /dev/null and b/modular_oculis/modules/storm/icons/redspace_anchor.dmi differ diff --git a/modular_oculis/modules/storm/readme.md b/modular_oculis/modules/storm/readme.md new file mode 100644 index 000000000000..240aade61c71 --- /dev/null +++ b/modular_oculis/modules/storm/readme.md @@ -0,0 +1,29 @@ +https://github.com/Monkestation/OculisStation/pull/46 + +## \ + +Module ID: EIDOLON_STORM + +### Description: + +This module is responsible for Eidolon's storm, anchor, as well as how both work mechanically. + +### TG Proc/File Changes: + +- `code/__DEFINES/wires.dm` + +### Modular Overrides: + +- N/A + +### Defines: + +- N/A + +### Included files that are not contained in this module: + +- `tgui/packages/tgui/interfaces/RedspaceAnchor.tsx` + +### Credits: + +XeonMations diff --git a/tgstation.dme b/tgstation.dme index 2a2dc4021c4d..faf511753978 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -10332,6 +10332,13 @@ #include "modular_oculis\modules\species\ethereal\code\stomach_ethereal.dm" #include "modular_oculis\modules\stickers\code\boxes.dm" #include "modular_oculis\modules\stickers\code\stickers.dm" +#include "modular_oculis\modules\storm\code\anchor\anchor_computer.dm" +#include "modular_oculis\modules\storm\code\anchor\redspace_anchor.dm" +#include "modular_oculis\modules\storm\code\anchor\redspace_anchor_soundloop.dm" +#include "modular_oculis\modules\storm\code\anchor\wires.dm" +#include "modular_oculis\modules\storm\code\storm\storm_layer.dm" +#include "modular_oculis\modules\storm\code\storm\storm_rulesets.dm" +#include "modular_oculis\modules\storm\code\storm\storm_subsystem.dm" #include "modular_oculis\modules\tg_lizards\code\tails.dm" #include "modular_oculis\modules\turfs\oculis_turfs.dm" #include "modular_oculis\modules\unique_lizards\code\client_colour.dm" diff --git a/tgui/packages/tgui/interfaces/RedspaceAnchor.tsx b/tgui/packages/tgui/interfaces/RedspaceAnchor.tsx new file mode 100644 index 000000000000..fea6375b90c5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/RedspaceAnchor.tsx @@ -0,0 +1,86 @@ +// THIS IS A OCULIS UI FILE +import { + Box, + Button, + LabeledList, + NoticeBox, + ProgressBar, + Section, +} from 'tgui-core/components'; + +import { useBackend } from '../backend'; +import { Window } from '../layouts'; + +export const RedspaceAnchor = (props) => { +const { data } = useBackend(); +const { operational } = data; +return ( + + + {!operational && No data available} + {!!operational && } + + + ); +}; + +const RedspaceAnchorContent = (props) => { +const { act, data } = useBackend(); +const { breaker, charge_count, charging_state, on, operational, violetspace_energy } = data; +return ( +
+ + +
+ ); +};