mirror of
https://github.com/goonstation/goonstation-2020.git
synced 2026-07-17 01:52:21 +01:00
451 lines
13 KiB
Plaintext
451 lines
13 KiB
Plaintext
|
|
/* ==================== Area ==================== */
|
|
|
|
/area/station/shield_zone
|
|
icon_state = "shield_zone"
|
|
|
|
/* ==================== Generator ==================== */
|
|
|
|
/obj/machinery/shield_generator
|
|
name = "shield generator"
|
|
desc = "Some kinda thing what generates a big ol' shield around everything."
|
|
icon = 'icons/obj/32x96.dmi'
|
|
icon_state = "shieldgen0"
|
|
anchored = 1
|
|
density = 1
|
|
bound_height = 96
|
|
var/obj/machinery/power/data_terminal/link = null
|
|
var/net_id = null
|
|
var/list/shields = list()
|
|
var/active = 0
|
|
var/image/image_active = null
|
|
var/image/image_shower_dir = null
|
|
var/sound_startup = 'sound/machines/shieldgen_startup.ogg' // 40
|
|
var/sound_shutoff = 'sound/machines/shieldgen_shutoff.ogg' // 35
|
|
var/lastuse = 0
|
|
|
|
New()
|
|
..()
|
|
src.update_icon()
|
|
SPAWN_DBG(6 DECI SECONDS)
|
|
if (!src.link)
|
|
var/turf/T = get_turf(src)
|
|
var/obj/machinery/power/data_terminal/test_link = locate() in T
|
|
if (test_link && !test_link.is_valid_master(test_link.master))
|
|
src.link = test_link
|
|
src.link.master = src
|
|
src.net_id = generate_net_id(src)
|
|
|
|
proc/update_icon()
|
|
if (status & (NOPOWER|BROKEN))
|
|
src.icon_state = "shieldgen0"
|
|
src.UpdateOverlays(null, "top_lights")
|
|
src.UpdateOverlays(null, "meteor_dir1")
|
|
src.UpdateOverlays(null, "meteor_dir2")
|
|
src.UpdateOverlays(null, "meteor_dir3")
|
|
src.UpdateOverlays(null, "meteor_dir4")
|
|
return
|
|
|
|
if (src.active)
|
|
src.icon_state = "shieldgen-anim"
|
|
if (!src.image_active)
|
|
src.image_active = image(src.icon, "shield-top_anim")
|
|
src.UpdateOverlays(src.image_active, "top_lights")
|
|
else
|
|
src.icon_state = "shieldgen1"
|
|
src.UpdateOverlays(null, "top_lights")
|
|
|
|
if (meteor_shower_active)
|
|
if (!src.image_shower_dir)
|
|
src.image_shower_dir = image(src.icon, "shield-D[meteor_shower_active]")
|
|
src.image_shower_dir.icon_state = "shield-D[meteor_shower_active]"
|
|
src.UpdateOverlays(src.image_shower_dir, "meteor_dir[meteor_shower_active]")
|
|
else
|
|
src.UpdateOverlays(null, "meteor_dir1")
|
|
src.UpdateOverlays(null, "meteor_dir2")
|
|
src.UpdateOverlays(null, "meteor_dir3")
|
|
src.UpdateOverlays(null, "meteor_dir4")
|
|
|
|
process()
|
|
//src.update_icon()
|
|
if (status & BROKEN)
|
|
src.deactivate()
|
|
return
|
|
..()
|
|
if (status & NOPOWER)
|
|
src.deactivate()
|
|
return
|
|
src.use_power(250)
|
|
if (src.shields.len)
|
|
src.use_power(5*src.shields.len)
|
|
|
|
disposing()
|
|
src.remove_shield()
|
|
src.link = null
|
|
src.image_active = null
|
|
src.image_shower_dir = null
|
|
..()
|
|
|
|
receive_signal(datum/signal/signal)
|
|
if (status & (NOPOWER|BROKEN) || !src.link)
|
|
return
|
|
if (!signal || !src.net_id || signal.encryption)
|
|
return
|
|
|
|
if (signal.transmission_method != TRANSMISSION_WIRE) //No radio for us thanks
|
|
return
|
|
|
|
var/target = signal.data["sender"]
|
|
|
|
//They don't need to target us specifically to ping us.
|
|
//Otherwise, ff they aren't addressing us, ignore them
|
|
if (signal.data["address_1"] != src.net_id)
|
|
if ((signal.data["address_1"] == "ping") && signal.data["sender"])
|
|
SPAWN_DBG(5 DECI SECONDS) //Send a reply for those curious jerks
|
|
src.post_status(target, "command", "ping_reply", "device", "PNET_SHIELD_GEN", "netid", src.net_id)
|
|
return
|
|
|
|
var/sigcommand = lowertext(signal.data["command"])
|
|
if (!sigcommand || !signal.data["sender"])
|
|
return
|
|
|
|
switch (sigcommand)
|
|
if ("activate")
|
|
if (src.active)
|
|
src.post_reply("SGEN_ACT", target)
|
|
return
|
|
src.activate()
|
|
src.post_reply("SGEN_ACTVD", target)
|
|
|
|
if ("deactivate")
|
|
if (!src.active)
|
|
src.post_reply("SGEN_NACT", target)
|
|
return
|
|
src.deactivate()
|
|
src.post_reply("SGEN_DACTVD", target)
|
|
|
|
// for testing atm
|
|
attack_hand(mob/user as mob)
|
|
|
|
var/diff = world.timeofday - lastuse
|
|
if(diff < 0) diff += 864000 //Wrapping protection.
|
|
|
|
|
|
if(diff > 1500)
|
|
lastuse = world.timeofday
|
|
user.show_text("You flip the switch on [src].")
|
|
if (src.active)
|
|
src.deactivate()
|
|
else
|
|
src.activate()
|
|
message_admins("<span style=\"color:blue\">[key_name(user)] [src.active ? "activated" : "deactivated"] shields</span>")
|
|
logTheThing("station", null, null, "[key_name(user)] [src.active ? "activated" : "deactivated"] shields")
|
|
else
|
|
user.show_text("<span style='color:red'><b>That is still not ready to be used again.</b></span>")
|
|
|
|
proc/post_status(var/target_id, var/key, var/value, var/key2, var/value2, var/key3, var/value3)
|
|
if (!src.link || !target_id)
|
|
return
|
|
|
|
var/datum/signal/signal = get_free_signal()
|
|
signal.source = src
|
|
signal.transmission_method = TRANSMISSION_WIRE
|
|
signal.data[key] = value
|
|
if (key2)
|
|
signal.data[key2] = value2
|
|
if (key3)
|
|
signal.data[key3] = value3
|
|
|
|
signal.data["address_1"] = target_id
|
|
signal.data["sender"] = src.net_id
|
|
|
|
src.link.post_signal(src, signal)
|
|
|
|
proc/post_reply(error_text, target_id)
|
|
if (!error_text || !target_id)
|
|
return
|
|
SPAWN_DBG(3 DECI SECONDS)
|
|
src.post_status(target_id, "command", "device_reply", "status", error_text)
|
|
return
|
|
|
|
proc/create_shield()
|
|
var/area/shield_loc = locate(/area/station/shield_zone)
|
|
for (var/turf/T in shield_loc)
|
|
if (!(locate(/obj/forcefield/meteorshield) in T))
|
|
var/obj/forcefield/meteorshield/MS = new /obj/forcefield/meteorshield(T)
|
|
MS.deployer = src
|
|
src.shields += MS
|
|
|
|
proc/remove_shield()
|
|
for (var/obj/forcefield/meteorshield/MS in src.shields)
|
|
MS.deployer = null
|
|
src.shields -= MS
|
|
qdel(MS)
|
|
|
|
proc/activate()
|
|
if (src.active)
|
|
return
|
|
src.active = 1
|
|
src.create_shield()
|
|
src.update_icon()
|
|
playsound(src.loc, src.sound_startup, 75)
|
|
|
|
proc/deactivate()
|
|
if (!src.active)
|
|
return
|
|
src.active = 0
|
|
src.remove_shield()
|
|
src.update_icon()
|
|
playsound(src.loc, src.sound_shutoff, 75)
|
|
|
|
|
|
/obj/machinery/shield_generator/console_upper
|
|
icon = 'icons/obj/computerpanel.dmi'
|
|
icon_state = "engine1"
|
|
|
|
update_icon()
|
|
return
|
|
|
|
/obj/machinery/shield_generator/console_lower
|
|
icon = 'icons/obj/computerpanel.dmi'
|
|
icon_state = "engine2"
|
|
|
|
update_icon()
|
|
return
|
|
|
|
/* ==================== Computer ==================== */
|
|
|
|
/obj/machinery/computer3/generic/shield_control
|
|
name = "shield control computer"
|
|
icon_state = "engine"
|
|
base_icon_state = "engine"
|
|
setup_drive_size = 48
|
|
|
|
setup_starting_peripheral1 = /obj/item/peripheral/network/powernet_card
|
|
//setup_starting_peripheral2 = /obj/item/peripheral/network/radio/locked/pda
|
|
setup_starting_program = /datum/computer/file/terminal_program/shield_control
|
|
|
|
/obj/machinery/computer3/generic/shield_control/console_upper
|
|
icon = 'icons/obj/computerpanel.dmi'
|
|
icon_state = "engine1"
|
|
base_icon_state = "engine1"
|
|
/obj/machinery/computer3/generic/shield_control/console_lower
|
|
icon = 'icons/obj/computerpanel.dmi'
|
|
icon_state = "engine2"
|
|
base_icon_state = "engine2"
|
|
|
|
/* ==================== Program ==================== */
|
|
|
|
/datum/computer/file/terminal_program/shield_control
|
|
name = "ShieldControl"
|
|
size = 10
|
|
req_access = list(access_engineering_engine)
|
|
var/tmp/authenticated = null //Are we currently logged in?
|
|
var/datum/computer/file/user_data/account = null
|
|
var/obj/item/peripheral/network/powernet_card/pnet_card = null
|
|
var/tmp/gen_net_id = null //The net id of our linked generator
|
|
var/tmp/reply_wait = -1 //How long do we wait for replies? -1 is not waiting.
|
|
|
|
var/setup_acc_filepath = "/logs/sysusr"//Where do we look for login data?
|
|
|
|
initialize()
|
|
src.authenticated = null
|
|
src.master.temp = null
|
|
if (!src.find_access_file()) //Find the account information, as it's essentially a ~digital ID card~
|
|
src.print_text("<b>Error:</b> Cannot locate user file. Quitting...")
|
|
src.master.unload_program(src) //Oh no, couldn't find the file.
|
|
return
|
|
|
|
src.pnet_card = locate() in src.master.peripherals
|
|
if (!pnet_card || !istype(src.pnet_card))
|
|
src.pnet_card = null
|
|
src.print_text("<b>Warning:</b> No network adapter detected.")
|
|
|
|
if (!src.check_access(src.account.access))
|
|
src.print_text("User [src.account.registered] does not have needed access credentials.<br>Quitting...")
|
|
src.master.unload_program(src)
|
|
return
|
|
|
|
src.reply_wait = -1
|
|
src.authenticated = src.account.registered
|
|
|
|
var/intro_text = {"<b>ShieldControl</b>
|
|
<br>Emergency Defense Shield System
|
|
<br><b>Commands:</b>
|
|
<br>(Link) to link with a shield generator.
|
|
<br>(Activate) to activate shields.
|
|
<br>(Deactivate) to deactivate shields.
|
|
<br>(Clear) to clear the screen.
|
|
<br>(Quit) to exit ShieldControl."}
|
|
src.print_text(intro_text)
|
|
|
|
input_text(text)
|
|
if (..())
|
|
return
|
|
|
|
var/list/command_list = parse_string(text)
|
|
var/command = command_list[1]
|
|
command_list -= command_list[1] //Remove the command we are now processing.
|
|
|
|
switch (lowertext(command))
|
|
|
|
if ("link")
|
|
if (!src.pnet_card) //can't do this ~fancy network stuff~ without a network card.
|
|
src.print_text("<b>Error:</b> Network card required.")
|
|
src.master.add_fingerprint(usr)
|
|
return
|
|
|
|
src.print_text("Now scanning for shield generator...")
|
|
src.detect_generator()
|
|
|
|
if ("activate")
|
|
if (!src.pnet_card)
|
|
src.print_text("<b>Error:</b> Network card required.")
|
|
src.master.add_fingerprint(usr)
|
|
return
|
|
|
|
if (!src.gen_net_id)
|
|
src.detect_generator()
|
|
sleep(8)
|
|
if (!src.gen_net_id)
|
|
src.print_text("<b>Error:</b> Unable to detect generator. Please check network cabling.")
|
|
return
|
|
else
|
|
src.print_text("Transmitting activation request...")
|
|
generate_signal(gen_net_id, "command", "activate")
|
|
|
|
if ("deactivate")
|
|
if (!src.pnet_card)
|
|
src.print_text("<b>Error:</b> Network card required.")
|
|
src.master.add_fingerprint(usr)
|
|
return
|
|
|
|
if (!src.gen_net_id)
|
|
src.detect_generator()
|
|
sleep(8)
|
|
if (!src.gen_net_id)
|
|
src.print_text("<b>Error:</b> Unable to detect generator. Please check network cabling.")
|
|
return
|
|
else
|
|
src.print_text("Transmitting deactivation request...")
|
|
generate_signal(gen_net_id, "command", "deactivate")
|
|
|
|
if ("help")
|
|
var/help_text = {"<br><b>ShieldControl</b>
|
|
<br>Emergency Defense Shield System
|
|
<br><b>Commands:</b>
|
|
<br>(Link) to link with a shield generator.
|
|
<br>(Activate) to activate shields.
|
|
<br>(Deactivate) to deactivate shields.
|
|
<br>(Clear) to clear the screen.
|
|
<br>(Quit) to exit ShieldControl."}
|
|
src.print_text(help_text)
|
|
|
|
if ("clear")
|
|
src.master.temp = null
|
|
src.master.temp_add = "Workspace cleared.<br>"
|
|
|
|
if ("quit")
|
|
src.master.temp = ""
|
|
print_text("Now quitting...")
|
|
src.master.unload_program(src)
|
|
return
|
|
|
|
else
|
|
print_text("Unknown command : \"[copytext(strip_html(command), 1, 16)]\"")
|
|
|
|
src.master.add_fingerprint(usr)
|
|
src.master.updateUsrDialog()
|
|
return
|
|
|
|
process()
|
|
if (..())
|
|
return
|
|
|
|
if (src.reply_wait > 0)
|
|
src.reply_wait--
|
|
if (src.reply_wait == 0)
|
|
src.print_text("Timed out on generator. Please rescan and retry.")
|
|
src.gen_net_id = null
|
|
|
|
receive_command(obj/source, command, datum/signal/signal)
|
|
if ((..()) || (!signal))
|
|
return
|
|
|
|
//If we don't have a generator net_id to use, set one.
|
|
switch (signal.data["command"])
|
|
if ("ping_reply")
|
|
if (src.gen_net_id)
|
|
return
|
|
if ((signal.data["device"] != "PNET_SHIELD_GEN") || !signal.data["netid"])
|
|
return
|
|
|
|
src.gen_net_id = signal.data["netid"]
|
|
src.print_text("Shield generator detected.")
|
|
|
|
if ("device_reply")
|
|
if (!src.gen_net_id || signal.data["sender"] != src.gen_net_id)
|
|
return
|
|
|
|
src.reply_wait = -1
|
|
|
|
switch (lowertext(signal.data["status"]))
|
|
if ("sgen_act")
|
|
src.print_text("<b>Alert:</b> Shield generator is already active.")
|
|
|
|
if ("sgen_nact")
|
|
src.print_text("<b>Alert:</b> Shield generator is already inactive.")
|
|
|
|
if ("sgen_actvd")
|
|
src.print_text("<b>Alert:</b> Shield generator activated.")
|
|
if (master && master.current_user)
|
|
message_admins("<span style=\"color:blue\">[key_name(master.current_user)] activated shields</span>")
|
|
logTheThing("station", null, null, "[key_name(master.current_user)] activated shields")
|
|
|
|
if ("sgen_dactvd")
|
|
src.print_text("<b>Alert:</b> Shield generator deactivated.")
|
|
if (master && master.current_user)
|
|
message_admins("<span style=\"color:blue\">[key_name(master.current_user)] deactivated shields</span>")
|
|
logTheThing("station", null, null, "[key_name(master.current_user)] deactivated shields")
|
|
return
|
|
return
|
|
|
|
proc/find_access_file() //Look for the whimsical account_data file
|
|
var/datum/computer/folder/accdir = src.holder.root
|
|
if (src.master.host_program) //Check where the OS is, preferably.
|
|
accdir = src.master.host_program.holder.root
|
|
|
|
var/datum/computer/file/user_data/target = parse_file_directory(setup_acc_filepath, accdir)
|
|
if (target && istype(target))
|
|
src.account = target
|
|
return 1
|
|
|
|
return 0
|
|
|
|
proc/detect_generator() //Send out a ping signal to find a comm dish.
|
|
if (!src.pnet_card)
|
|
return //The card is kinda crucial for this.
|
|
|
|
var/datum/signal/newsignal = get_free_signal()
|
|
//newsignal.encryption = "\ref[src.pnet_card]"
|
|
|
|
src.gen_net_id = null
|
|
src.reply_wait = -1
|
|
src.peripheral_command("ping", newsignal, "\ref[src.pnet_card]")
|
|
|
|
proc/generate_signal(var/target_id, var/key, var/value, var/key2, var/value2, var/key3, var/value3)
|
|
if (!src.pnet_card || !gen_net_id)
|
|
return
|
|
|
|
var/datum/signal/signal = get_free_signal()
|
|
//signal.encryption = "\ref[src.pnet_card]"
|
|
signal.data["address_1"] = target_id
|
|
signal.data[key] = value
|
|
if (key2)
|
|
signal.data[key2] = value2
|
|
if (key3)
|
|
signal.data[key3] = value3
|
|
|
|
src.reply_wait = 5
|
|
src.peripheral_command("transmit", signal, "\ref[src.pnet_card]")
|