Calling the emergency shuttle now requires a physical button (#3509)

The emergency shuttle can now be called by using a physical button in a protected case.
The option to call the emergency shuttle has been removed from the command and communications app.
Also adds a framework for physical buttons in a protected case.
The emergency shuttle button needs to be mapped in.
This commit is contained in:
Werner
2017-10-01 15:25:21 +02:00
committed by Erki
parent e94ec752a0
commit e759e4386d
9 changed files with 215 additions and 21 deletions
+1
View File
@@ -480,6 +480,7 @@
#include "code\game\machinery\bluespacerelay.dm"
#include "code\game\machinery\buttons.dm"
#include "code\game\machinery\CableLayer.dm"
#include "code\game\machinery\case_button.dm"
#include "code\game\machinery\cell_charger.dm"
#include "code\game\machinery\cloning.dm"
#include "code\game\machinery\constructable_frame.dm"
+111
View File
@@ -0,0 +1,111 @@
//TODO: Fix Power Usage
/obj/machinery/case_button
name = "Forcefield Button"
desc = "A button in a case protected with a forcefield."
icon = 'icons/obj/glasscasebutton.dmi'
icon_state = "c1"
anchored = 1
use_power = 1
idle_power_usage = 50 //50W because the forcefield is disabled
active_power_usage = 2000 //2kW because of the forcefield
power_channel = EQUIP
req_access = list(access_keycard_auth) //Access required to unlock the cover
//Style variables
var/case = 1 //What case to use - c value
var/cover = 1 //What cover to use - g value
var/button = 1 //What button to use - b value
//Status variables
var/covered = 1 //If the cover is active
var/active = 0 //If the button is active
var/button_type = "button_case_generic" //Button type for the listener
var/listener/listener //Listener for button updates
//Spam Protection
var/last_toggle_time = 0
var/timeout = 10 //How long you have to wait between pressing the button
/obj/machinery/case_button/Initialize()
. = ..()
listener = new(button_type, src)
update_icon()
/obj/machinery/case_button/Destroy()
QDEL_NULL(listener)
return ..()
/obj/machinery/case_button/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/card))
if(src.allowed(user))
covered = !covered //Enable / Disable the forcefield
update_use_power(covered + 1) //Update the power usage
else
if(covered && (stat & NOPOWER)) //Only bounce off if its powered (i.e. shield active)
..()
else
user.visible_message("<span class='danger'>[src] has been hit by [user] with [W], but it bounces off the forcefield.</span>","<span class='danger'>You hit [src] with [W], but it bounces off the forcefield.</span>","You hear something boucing off a forcefield.")
update_icon()
return
/obj/machinery/case_button/attack_hand(mob/user as mob)
if(!covered)
//Spam Check
if((last_toggle_time + timeout) > world.time)
user.visible_message("<span class='notice'>\The [user] presses the button, but nothing happens.</span>","<span class='notice'>You press the button, but it is not responding.</span>","You hear something being pressed.")
return ..()
last_toggle_time = world.time
if(!active)
if(activate(user))
for(var/button in get_listeners_by_type(button_type,/obj/machinery/case_button))
var/obj/machinery/case_button/cb = button
cb.active = 1
cb.update_icon()
else
if(deactivate(user))
for(var/button in get_listeners_by_type(button_type,/obj/machinery/case_button))
var/obj/machinery/case_button/cb = button
cb.active = 0
cb.update_icon()
else
..()
return
/obj/machinery/case_button/power_change()
. = ..()
update_icon()
return
/obj/machinery/case_button/update_icon()
cut_overlays()
if(stat & NOPOWER)
update_use_power(0)
add_overlay("b[button]d") //Add the deactivated button overlay
add_overlay("g[cover]d") //Add the deactivated cover overlay
return
add_overlay("b[button][active]") //Add the button as overlay
add_overlay("g[cover][covered]") //Add the glass/shield overlay
return
//Activate the button - Needs to return 1 for the activation to be successful
/obj/machinery/case_button/proc/activate(mob/user)
user.visible_message("<span class='notice'>\The [user] presses the button.</span>","<span class='notice'>You press the button.</span>","You hear something being pressed.")
return 1
//Deactivate Button - Needs ro return 1 for the activation to be successful
/obj/machinery/case_button/proc/deactivate(mob/user)
user.visible_message("<span class='notice'>\The [user] resets the button.</span>","<span class='notice'>You reset the button.</span>","You hear something being pressed.")
return 1
/obj/machinery/case_button/shuttle
name = "\improper Emergency Shuttle Button"
desc = "A button in a case protected with a forcefield."
button_type = "button_case_emergencyshuttle"
/obj/machinery/case_button/shuttle/activate(mob/user)
..()
return call_shuttle_proc(user)
/obj/machinery/case_button/shuttle/deactivate(mob/user)
..()
return cancel_call_proc(user)
@@ -51,6 +51,17 @@
nano_printer.stored_paper = 20
card_slot = new/obj/item/weapon/computer_hardware/card_slot(src)
/obj/item/modular_computer/console/preset/captain/
_app_preset_name = "captain"
enrolled = 1
/obj/item/modular_computer/console/preset/captain/install_default_hardware()
..()
nano_printer = new/obj/item/weapon/computer_hardware/nano_printer(src)
nano_printer.max_paper = 25
nano_printer.stored_paper = 20
card_slot = new/obj/item/weapon/computer_hardware/card_slot(src)
// Security
/obj/item/modular_computer/console/preset/security/
_app_preset_name = "security"
@@ -78,6 +78,25 @@
)
return _prg_list
/datum/modular_computer_app_presets/captain
name = "captain"
display_name = "Captain"
description = "Contains the most important programs for the Captain."
available = 0
/datum/modular_computer_app_presets/captain/return_install_programs()
var/list/_prg_list = list(
new/datum/computer_file/program/filemanager(),
new/datum/computer_file/program/chatclient(),
new/datum/computer_file/program/card_mod(),
new/datum/computer_file/program/comm(1,1),
new/datum/computer_file/program/camera_monitor(),
new/datum/computer_file/program/digitalwarrant(),
new/datum/computer_file/program/civilian/cargocontrol(),
new/datum/computer_file/program/civilian/cargoorder(),
new/datum/computer_file/program/alarm_monitor()
)
return _prg_list
/datum/modular_computer_app_presets/security
name = "security"
display_name = "Security"
@@ -17,11 +17,13 @@
network_destination = "station long-range communication array"
var/datum/comm_message_listener/message_core = new
var/intercept = 0
var/can_call_shuttle = 0 //If calling the shuttle should be available from this console
color = LIGHT_COLOR_BLUE
/datum/computer_file/program/comm/New(intercept_printing = 0)
/datum/computer_file/program/comm/New(intercept_printing = 0, shuttle_call = 0)
. = ..()
intercept = intercept_printing
can_call_shuttle = shuttle_call
/datum/computer_file/program/comm/clone()
var/datum/computer_file/program/comm/temp = ..()
@@ -65,6 +67,7 @@
data["have_printer"] = 0
data["message_printing_intercepts"] = 0
data["can_call_shuttle"] = can_call_shuttle()
data["message_line1"] = msg_line1
data["message_line2"] = msg_line2
data["state"] = current_status
@@ -112,6 +115,13 @@
return P.message_core
return global_message_listener
/datum/nano_module/program/comm/proc/can_call_shuttle()
if(program)
var/datum/computer_file/program/comm/P = program
return P.can_call_shuttle
else
return 0
/datum/nano_module/program/comm/Topic(href, href_list)
if(..())
return 1
@@ -180,7 +190,7 @@
spawn(300) //30 second cooldown
centcomm_message_cooldown = 0
if("shuttle")
if(is_autenthicated(user) && ntn_cont)
if(is_autenthicated(user) && ntn_cont && can_call_shuttle())
if(href_list["target"] == "call")
var/confirm = alert("Are you sure you want to call the shuttle?", name, "No", "Yes")
if(confirm == "Yes" && can_still_topic())
@@ -325,17 +335,19 @@ Command action procs
frequency.post_signal(src, status_signal)
//Returns 1 if recalled 0 if not
/proc/cancel_call_proc(var/mob/user)
if (!(ROUND_IS_STARTED) || !emergency_shuttle.can_recall())
return
return 0
if((SSticker.mode.name == "blob")||(SSticker.mode.name == "Meteor"))
return
return 0
if(!emergency_shuttle.going_to_centcom()) //check that shuttle isn't already heading to centcomm
emergency_shuttle.recall()
log_game("[key_name(user)] has recalled the shuttle.",key_name(user))
message_admins("[key_name_admin(user)] has recalled the shuttle.", 1)
return
return 1
return 0
/proc/is_relay_online()
@@ -344,44 +356,44 @@ Command action procs
return 1
return 0
//Returns 1 if called 0 if not
/proc/call_shuttle_proc(var/mob/user)
if ((!(ROUND_IS_STARTED) || !emergency_shuttle.location()))
return
return 0
if(!universe.OnShuttleCall(usr))
user << "<span class='notice'>Cannot establish a bluespace connection.</span>"
return
return 0
if(deathsquad.deployed)
user << "[boss_short] will not allow the shuttle to be called. Consider all contracts terminated."
return
return 0
if(emergency_shuttle.deny_shuttle)
user << "The emergency shuttle may not be sent at this time. Please try again later."
return
return 0
if(world.time < 6000) // Ten minute grace period to let the game get going without lolmetagaming. -- TLE
user << "The emergency shuttle is refueling. Please wait another [round((6000-world.time)/600)] minute\s before trying again."
return
return 0
if(emergency_shuttle.going_to_centcom())
user << "The emergency shuttle may not be called while returning to [boss_short]."
return
return 0
if(emergency_shuttle.online())
user << "The emergency shuttle is already on its way."
return
return 0
if(SSticker.mode.name == "blob")
user << "Under directive 7-10, [station_name()] is quarantined until further notice."
return
return 0
emergency_shuttle.call_evac()
log_game("[key_name(user)] has called the shuttle.",ckey=key_name(user))
message_admins("[key_name_admin(user)] has called the shuttle.", 1)
return
return 1
/proc/init_shift_change(var/mob/user, var/force = 0)
if ((!(ROUND_IS_STARTED) || !emergency_shuttle.location()))
+38
View File
@@ -0,0 +1,38 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
# balance
#################################
# Your name.
author: Arrow768
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- rscadd: "Added a button to call the emergency shuttle."
- rscdel: "It is no longer possible to call the shuttle using the command console."
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

+1 -1
View File
@@ -22958,7 +22958,7 @@
/turf/simulated/floor/wood,
/area/bridge/meeting_room)
"aOx" = (
/obj/item/modular_computer/console/preset/command,
/obj/item/modular_computer/console/preset/captain,
/turf/simulated/floor/carpet,
/area/crew_quarters/captain)
"aOy" = (
+7 -5
View File
@@ -7,11 +7,13 @@
{{:helper.link('Send an emergency message to ' + data.boss_short, null, {'action' : 'message', 'target' : 'regular'}, data.isAI || !data.net_comms ? 'disabled' : null)}}
{{/if}} </div>
<div class=item>{{:helper.link('Change alert level', null, {'action' : 'sw_menu', 'target' : 5}, data.isAI || !data.net_syscont || !data.net_comms ? 'disabled' : null)}} </div>
<div class=item>{{if data.have_shuttle && data.have_shuttle_called}}
{{:helper.link('Cancel Shuttle Call', null, {'action' : 'shuttle', 'target' : 'cancel'}, data.isAI || !data.net_syscont ? 'disabled' : null)}}
{{else data.have_shuttle && !data.have_shuttle_called}}
{{:helper.link('Call Emergency Shuttle', null, {'action' : 'shuttle', 'target' : 'call'}, !data.net_syscont ? 'disabled' : null)}}
{{/if}} </div>
{{if data.can_call_shuttle}}
<div class=item>{{if data.have_shuttle && data.have_shuttle_called}}
{{:helper.link('Cancel Shuttle Call', null, {'action' : 'shuttle', 'target' : 'cancel'}, data.isAI || !data.net_syscont ? 'disabled' : null)}}
{{else data.have_shuttle && !data.have_shuttle_called}}
{{:helper.link('Call Emergency Shuttle', null, {'action' : 'shuttle', 'target' : 'call'}, !data.net_syscont ? 'disabled' : null)}}
{{/if}} </div>
{{/if}}
<div class=item>{{:helper.link('Set Status Display', null, {'action' : 'sw_menu', 'target' : 4}, !data.net_syscont ? 'disabled' : null)}} </div>
<div class=item>{{:helper.link('Message List', null, {'action' : 'sw_menu', 'target' : 2}, !data.net_comms ? 'disabled' : null)}} </div>
{{else data.state === 2}}